精华内容
下载资源
问答
  • 运行时异常和非运行时异常

    万次阅读 2019-03-13 09:54:52
    1. 【强制】Java 类库中定义的可以通过预检查方式规避的RuntimeException异常不... 说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字,不得不通过catch NumberFormatException来实现。 正例:if (...

     

    1. 【强制】Java 类库中定义的可以通过预检查方式规避的RuntimeException异常不应该通过catch 的方式来处理,比如:NullPointerException,IndexOutOfBoundsException等等。 说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字时,不得不通过catch NumberFormatException来实现。 正例:if (obj != null) {...} 反例:try { obj.method(); } catch (NullPointerException e) {…}

     

     

     

     

     

     

     

     

    1.Java异常机制

    Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。Java中的异常分为两大类:错误Error和异常Exception,Java异常体系结构如下图所示:

    图片来源:http://blog.csdn.NET/wuwenxiang91322/article/details/10346337

     

    2.Throwable

    Throwable类是所有异常或错误的超类,它有两个子类:Error和Exception,分别表示错误和异常。其中异常Exception分为运行时异常(RuntimeException)和非运行时异常,也称之为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。

     

    3.Error

    一般是指java虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常应用程序无法处理这些错误,因此应用程序不应该捕获Error对象,也无须在其throws子句中声明该方法抛出任何Error或其子类。

     

    4.可查异常和不可查异常

    通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
    可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。
    除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
    不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。

    如果使用throw在方法体中抛出可查异常,则需要在方法头部声明方法可能抛出的异常类型。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

     

    5.运行时异常和非运行时异常

    (1)运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

    当出现RuntimeException的时候,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。 
    出现运行时异常后,如果没有捕获处理这个异常(即没有catch),系统会把异常一直往上层抛,一直到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。 
    如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。


    (2)非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

     

    定义 
    1、非运行时异常:是需要显示用try-catch捕捉处理的异常,如IOException等 
    2、运行时异常:不需要显示捕捉,如NullPointException等,常见于程序逻辑问题导致 
    背景 
    异常处理理论上有两种基本模型。终止模型,表示异常一旦发生就无法挽回,不能执行;恢复模型,功效类似于一个分支,通常希望异常被处理之后能继续执行程序。 
    区别 
    1、运行时异常:调用代码不能继续执行,需要立即终止。 
    2、非运行时异常:调用代码需要进一步处理和恢复 
    原则 
    1、非运行时异常是强迫使用者处理联动的操作,如sql执行失败需要关闭连接、回滚事务。此类异常若自己可以把关联处理掉则可转运行时异常。 
    2、运行时异常用于程序运行的检验、如前置条件校验、后置条件校验。 
    3、运行时异常用于运行的必要条件不具备时阻断程序运行,如连接服务器失败。 
    4、业务异常一般是条件检验的异常,基本用运行时异常声明。 
    5、系统在设计时,一般用检查异常标注可能存在的异常,用于告知开发者。 
    6、工具类中一般直接抛出原始的非运行时异常。
     

     

    展开全文
  • JVM详解之:运行时常量池

    万次阅读 2020-07-16 09:04:10
    JVM在运行的时候会对class文件进行加载,链接和初始化的过程。class文件中定义的常量池在JVM加载之后会发生什么神奇的变化呢?快来看一看吧。

    简介

    JVM在运行的时候会对class文件进行加载,链接和初始化的过程。class文件中定义的常量池在JVM加载之后会发生什么神奇的变化呢?快来看一看吧。

    class文件中的常量池

    之前我们在讲class文件的结构时,提到了每个class文件都有一个常量池,常量池中存了些什么东西呢?

    字符串常量,类和接口名字,字段名,和其他一些在class中引用的常量。

    运行时常量池

    但是只有class文件中的常量池肯定是不够的,因为我们需要在JVM中运行起来。

    这时候就需要一个运行时常量池,为JVM的运行服务。

    运行时常量池和class文件的常量池是一一对应的,它就是class文件的常量池来构建的。

    运行时常量池中有两种类型,分别是symbolic references符号引用和static constants静态常量。

    其中静态常量不需要后续解析,而符号引用需要进一步进行解析处理。

    什么是静态常量,什么是符号引用呢? 我们举个直观的例子。

    String site="www.flydean.com"
    

    上面的字符串"www.flydean.com"可以看做是一个静态常量,因为它是不会变化的,是什么样的就展示什么样的。

    而上面的字符串的名字“site”就是符号引用,需要在运行期间进行解析,为什么呢?

    因为site的值是可以变化的,我们不能在第一时间确定其真正的值,需要在动态运行中进行解析。

    静态常量详解

    运行时常量池中的静态常量是从class文件中的constant_pool构建的。可以分为两部分:String常量和数字常量。

    String常量

    String常量是对String对象的引用,是从class中的CONSTANT_String_info结构体构建的:

    CONSTANT_String_info {
        u1 tag;
        u2 string_index;
    }
    

    tag就是结构体的标记,string_index是string在class常量池的index。

    string_index对应的class常量池的内容是一个CONSTANT_Utf8_info结构体。

    CONSTANT_Utf8_info {
        u1 tag;
        u2 length;
        u1 bytes[length];
    }
    

    CONSTANT_Utf8_info是啥呢?它就是要创建的String对象的变种UTF-8编码。

    我们知道unicode的范围是从0x0000 至 0x10FFFF。

    变种UTF-8就是将unicode进行编码的方式。那是怎么编码呢?

    从上图可以看到,不同的unicode范围使用的是不同的编码方式。

    注意,如果一个字符占用多个字节,那么在class文件中使用的是 big-endian 大端优先的排列方式。

    如果字符范围在FFFF之后,那么使用的是2个3字节的格式的组合。

    讲完class文件中CONSTANT_String_info的结构之后,我们再来看看从CONSTANT_String_info创建运行时String常量的规则:

    1. 规则一:如果String.intern之前被调用过,并且返回的结果和CONSTANT_String_info中保存的编码是一致的话,表示他们指向的是同一个String的实例。

    2. 规则二:如果不同的话,那么会创建一个新的String实例,并将运行时String常量指向该String的实例。最后会在这个String实例上调用String的intern方法。调用intern方法主要是将这个String实例加入字符串常量池。

    数字常量

    数字常量是从class文件中的CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info和 CONSTANT_Double_info 构建的。

    符号引用详解

    符号引用也是从class中的constant_pool中构建的。

    对class和interface的符号引用来自于CONSTANT_Class_info。

    对class和interface中字段的引用来自于CONSTANT_Fieldref_info。

    class中方法的引用来自于CONSTANT_Methodref_info。

    interface中方法的引用来自于CONSTANT_InterfaceMethodref_info。

    对方法句柄的引用来自于CONSTANT_MethodHandle_info。

    对方法类型的引用来自于CONSTANT_MethodType_info。

    对动态计算常量的符号引用来自于CONSTANT_MethodType_info。

    对动态计算的call site的引用来自于CONSTANT_InvokeDynamic_info。

    String Pool字符串常量池

    我们在讲到运行时常量池的时候,有提到String常量是对String对象的引用。那么这些创建的String对象是放在什么地方呢?

    没错,就是String Pool字符串常量池。

    这个String Pool在每个JVM中都只会维护一份。是所有的类共享的。

    String Pool是在1.6之前是存放在方法区的。在1.8之后被放到了java heap中。

    注意,String Pool中存放的是字符串的实例,也就是用双引号引起来的字符串。

    那么问题来了?

    String name = new String("www.flydean.com";
    

    到底创建了多少个对象呢?

    总结

    class文件中常量池保存的是字符串常量,类和接口名字,字段名,和其他一些在class中引用的常量。每个class都有一份。

    运行时常量池保存的是从class文件常量池构建的静态常量引用和符号引用。每个class都有一份。

    字符串常量池保存的是“字符”的实例,供运行时常量池引用。

    运行时常量池是和class或者interface一一对应的,那么如果一个class生成了两个实例对象,这两个实例对象是共享一个运行时常量池还是分别生成两个不同的常量池呢?欢迎小伙伴们留言讨论。

    本文链接:http://www.flydean.com/jvm-run-time-constant-pool/

    最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

    展开全文
  • 运行时常量池是当Class文件被加载到内存后,Java虚拟机会 将Class文件常量池里的内容转移到运行时常量池里(运行时常量池也是每个类都有一个)。运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,...

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站。博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事,做自己以后不会留有遗憾的事,做自己觉得有意义的事,不浪费这大好的青春年华。博主写博客目的是记录所学到的知识并方便自己复习,在记录知识的同时获得部分浏览量,得到更多人的认可,满足小小的成就感,同时在写博客的途中结交更多志同道合的朋友,让自己在技术的路上并不孤单。>本篇博客由于比较深入的写进JVM底层,所以如果有错误希望可以指出咱们共同讨论

    痛苦对我们来说,究竟意味着什么?司马迁在《报任安书》中一语道破,文王拘而演《周易》,仲尼厄而作《春秋》,屈原放逐乃赋《离骚》,左丘失明厥有《国语》。

    目录:
    1.常量池与Class常量池
    2.运行时常量池
           
    运行时常量池的简介
           
    方法区的Class文件信息,Class常量池和运行时常量池的三者关系
    3.字符串常量池
           
    字符串常量池的简介
           
    采用字面值的方式创建字符串对象
           
    采用new关键字新建一个字符串对象
           
    字符串池的优缺点
    4.字符串常量池和运行时常量池之间的藕断丝连
           
    常量池和字符串常量池的版本变化
           
    String.intern在JDK6和JDK7之后的区别(重难点)
           
    字符串常量池里存放的是引用还是字面量

    在这里插入图片描述

    1.常量池

    常量池,也叫 Class 常量池(常量池==Class常量池)。Java文件被编译成 Class文件,Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是常量池,常量池是当Class文件被Java虚拟机加载进来后存放在方法区 各种字面量 (Literal)和 符号引用

    在Class文件结构中,最头的4个字节用于 存储魔数 (Magic Number),用于确定一个文件是否能被JVM接受,再接着4个字节用于 存储版本号,前2个字节存储次版本号,后2个存储主版本号,再接着是用于存放常量的常量池常量池主要用于存放两大类常量:字面量和符号引用量,字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念。如下

    在这里插入图片描述

    在这里插入图片描述

    2.运行时常量池

    2.1运行时常量池的简介

    运行时常量池是方法区的一部分。运行时常量池是当Class文件被加载到内存后,Java虚拟机会 将Class文件常量池里的内容转移到运行时常量池里(运行时常量池也是每个类都有一个)。运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中

    2.2方法区的Class文件信息,Class常量池和运行时常量池的三者关系

    在这里插入图片描述

    字符串常量池

    3.1字符串常量池的简介

    字符串常量池又称为:字符串池,全局字符串池,英文也叫String Pool。 在工作中,String类是我们使用频率非常高的一种对象类型。JVM为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,这就是我们今天要讨论的核心:字符串常量池。字符串常量池由String类私有的维护

    我们理清几个概念:

    在JDK7之前字符串常量池是在永久代里边的,但是在JDK7之后,把字符串常量池分进了堆里边。看下面两张图:

    在这里插入图片描述

    在堆中的字符串常量池: **堆里边的字符串常量池存放的是字符串的引用或者字符串(两者都有)**下面例子会有具体的讲解

    在这里插入图片描述

    符号引用表会在下面讲

    我们知道,在Java中有两种创建字符串对象的方式:

    1. 采用字面值的方式赋值
    2. 采用new关键字新建一个字符串对象。这两种方式在性能和内存占用方面存在着差别。

    3.2采用字面值的方式创建字符串对象

    package Oneday;
    public class a {
        public static void main(String[] args) {
            String str1="aaa";
            String str2="aaa";
            System.out.println(str1==str2);   
        }
    }
    运行结果:
    true
    

    采用字面值的方式创建一个字符串时,JVM首先会去字符串池中查找是否存在"aaa"这个对象,如果不存在,则在字符串池中创建"aaa"这个对象,然后将池中"aaa"这个对象的引用地址返回给字符串常量str,这样str会指向池中"aaa"这个字符串对象;如果存在,则不创建任何对象,直接将池中"aaa"这个对象的地址返回,赋给字符串常量。

    对于上述的例子:这是因为,创建字符串对象str2时,字符串池中已经存在"aaa"这个对象,直接把对象"aaa"的引用地址返回给str2,这样str2指向了池中"aaa"这个对象,也就是说str1和str2指向了同一个对象,因此语句System.out.println(str1== str2)输出:true

    3.3采用new关键字新建一个字符串对象

    package Oneday;
    public class a {
        public static void main(String[] args) {
            String str1=new String("aaa");
            String str2=new String("aaa");
            System.out.println(str1==str2);
        }
    }
    运行结果:
    false
    

    采用new关键字新建一个字符串对象时,JVM首先在字符串常量池中查找有没有"aaa"这个字符串对象,如果有,则不在池中再去创建"aaa"这个对象了,直接在堆中创建一个"aaa"字符串对象,然后将堆中的这个"aaa"对象的地址返回赋给引用str1,这样,str1就指向了堆中创建的这个"aaa"字符串对象;如果没有,则首先在字符串常量池池中创建一个"aaa"字符串对象,然后再在堆中创建一个"aaa"字符串对象,然后将堆中这个"aaa"字符串对象的地址返回赋给str1引用,这样,str1指向了堆中创建的这个"aaa"字符串对象。

    对于上述的例子:
    因为,采用new关键字创建对象时,每次new出来的都是一个新的对象,也即是说引用str1和str2指向的是两个不同的对象,因此语句
    System.out.println(str1 == str2)输出:false

    字符串池的实现有一个前提条件:String对象是不可变的。因为这样可以保证多个引用可以同时指向字符串池中的同一个对象。如果字符串是可变的,那么一个引用操作改变了对象的值,对其他引用会有影响,这样显然是不合理的。

    3.4字符串池的优缺点

    字符串池的优点就是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;另一方面,字符串池的缺点就是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低。

    4字符串常量池和运行时常量池之间的藕断丝连

    博主为啥要把他俩放在一起讲呢,主要是随着JDK的改朝换代,字符串常量池有很大的变动,和运行时常量池有关。而且网上众说纷纭,我真的在看的时候ctm了,所以博主花很长时间把这一块讲明白,如果有错误或者异议可以通知博主。博主一定会在第一时间参与讨论

    在这里插入图片描述

    4.1常量池和字符串常量池的版本变化

    • 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
    • 在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说 字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
    • 在JDK1.8 hotspot移除了永久代用元空间(Metaspace)取而代之, 这时候字符串常量池还在堆, 运行时常量池还在方法区, 只不过方法区的实现从永久代变成了元空间(Metaspace)

    4.2String.intern在JDK6和JDK7之后的区别(重点)

    JDK6和JDK7中该方法的功能是一致的,不同的是常量池位置的改变(JDK7将常量池放在了堆空间中),下面会具体说明。intern的方法返回字符串对象的规范表示形式。其中它做的事情是:首先去判断该字符串是否在常量池中存在,如果存在返回常量池中的字符串,如果在字符串常量池中不存在,先在字符串常量池中添加该字符串,然后返回引用地址

    例子1:

    String s1 = new String("1");
    s1.intern();
    String s2 = "1";
    System.out.println(s1 == s2);
    
    运行结果:
    JDK6运行结果:false
    JDK7运行结果:false
    

    我们首先看一张图:

    在这里插入图片描述上边例子中s1是new出来对象存放的位置的引用,s2是存放在字符串常量池的字符串的引用,所以两者不同

    例子2:

    String s1 = new String("1");
    System.out.println(s1.intern() == s1);
    
    运行结果:
    JDK6运行结果:false
    JDK7运行结果:false
    

    上边例子中s1是new出来对象存放的位置的引用,s1.intern()返回的是字符串常量池里字符串的引用

    例子3:

    String s1 = new String("1") + new String("1");
    s1.intern();
    String s2 = "11";
    System.out.println(s1 == s2);
    
    运行结果:
    JDK6运行结果:false
    JDK7运行结果:true
    

    JDK6中,s1.intern()运行时,首先去常量池查找,发现没有该常量,则在常量池中开辟空间存储"11",返回常量池中的值(注意这里也没有使用该返回值),第三行中,s2直接指向常量池里边的字符串,所以s1和s2不相等。有可能会有小伙伴问为啥s1.intern()发现没有该常量呢,那是因为:

    String s1 = new String(“1”) + new String(“1”);这行代码实际操作是,创建了一个StringBuilder对象,然后一路append,最后toString,而toString其实是又重新new了一个String对象,然后把对象给s1,此时并没有在字符串常量池中添加常量

    JDK7中,由于字符串常量池在堆空间中,所以在s1.intern()运行时,发现字符串 常量池没有常量,则添加堆中“11”对象的引用到字符串常量池,这个引用返回堆空间“11”地址(注意这里也没有使用该返回值),这时s2通过查找字符串常量池中的常量,查到的是s1.intern()存在字符串常量池里的“11”对象的引用,既然都是指向堆上的“11”对象,所以s1和s2相等。

    例子4:

    String s1 = new String("1") + new String("1");
    System.out.println(s1.intern() == s1);
    

    JDK6中,常量池在永久代中,s1.intern()去常量池中查找"11",发现没有该常量,则在常量池中开辟空间存储"11",返回常量池中的值,s1指向堆空间地址,所以二者不相等。

    JDK7中,常量池在堆空间,s1.intern()去常量池中查找"11",发现没有该常量,则在字符串常量池中开辟空间,指向堆空间地址,则返回字符串常量池指向的堆空间地址,s1也是堆空间地址,所以二者相等。

    另外美团的团队写了一篇关于intern()的博客,我觉得很好可以参考一下
    深入解析String#intern

    4.3字符串常量池里存放的是引用还是字面量

    我在例子3中讲了在JDK7中字符串常量池在堆上,仔细看看例3啥时候会放引用

    那么啥时候会放字面量在字符串常量池呢,那就是在我们new一个String对象的时候如果字符串常量池里边有字面量那么就不会放,如果字符串常量池没有就会放字面量。看一个例子:

    package Oneday;
    import java.util.HashSet;
    import java.util.Set;
    public class a {
        public static void main(String[] args) {
            String str1= new String("123");
            String str2=new String("123");
            System.out.println(str1==str2);
            System.out.println(str1.intern()==str2.intern());    
        }
    }
    

    运行结果:
    在这里插入图片描述
    首先 String str1= new String("123");会在堆中创建一个对象,返回这个对象的引用给str1,同时它还会在字符串常量池中检查有没有有没有123这个对象,如果没有就==再创建一个对象(也就是123这个字面量)==在字符串常量池中

    注意这里是创建了两个对象

    但是当我们字符串常量池里边有123这个对象,那么就不用继续创建了

    上面例子的false那是因为堆中的123对象不是同一个对象,但是第二个str1.intern和s2.intern指的都是字符串常量池里的123对象所以是true

    展开全文
  • Java运行时异常和非运行时异常

    千次阅读 2019-06-04 09:06:35
    1. Java异常机制 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。Java中的异常分为两大类:错误Error和异常Exception,Java异常体系结构如下图所示...其中异常Exception分为运行...

    1. Java异常机制

    Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。Java中的异常分为两大类:错误Error和异常Exception,Java异常体系结构如下图所示:

    2. Throwable

    Throwable类是所有异常或错误的超类,它有两个子类:Error和Exception,分别表示错误和异常。其中异常Exception分为运行时异常(RuntimeException)和非运行时异常,也称之为不检查异常(Unchecked Exception)和检查异常(Checked Exception)

    3. Error

    一般是指java虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常应用程序无法处理这些错误,因此应用程序不应该捕获Error对象,也无须在其throws子句中声明该方法抛出任何Error或其子类。

    4. 可查异常和不可查异常

    通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
    可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。
    除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
    不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。

    如果使用throw在方法体中抛出可查异常,则需要在方法头部声明方法可能抛出的异常类型。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

    5. 运行时异常和非运行时异常

    (1)运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

    当出现RuntimeException的时候,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
    出现运行时异常后,如果没有捕获处理这个异常(即没有catch),系统会把异常一直往上层抛,一直到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
    如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。

    (2)非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

    常见RuntimeException:

    ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常
    ClassCastException 试图将对象强制转换为不是实例的子类时,抛出该异常
    IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
    IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
    NoSuchElementException 表明枚举中没有更多的元素
    NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常

    展开全文
  • 浅谈Java异常及其编译时异常和运行时异常的区别

    千次阅读 多人点赞 2019-03-18 18:06:48
    异常是程序编码和运行时经常发生的事件,了解异常有助于我们提高代码质量,增强系统的健壮性,这里总结一下载Java编程中,编译时异常和运行异常时的区别,并列举几种常见的异常,以供参考学习。
  • Android 仿QQ后台运行时收到推送消息 在顶部弹出 源码,用到类似 Heads-up 组件的库。
  • 编译时多态、运行时多态

    万次阅读 多人点赞 2018-03-25 21:13:26
    根据何时确定执行多态方法中的哪一个,多态分为两种情况:编译时多态和运行时多态。如果在编译时能够确定执行多态方法中的哪一个,称为编译时多态,否则称为运行时多态。一、编译时多态 方法重载都是编译时多态。...
  • 理解C/C++运行时

    万次阅读 2018-03-14 15:57:54
    一、什么是运行时运行时库(Runtime library)通俗的说就是我们的程序运行的时候所依赖的库文件,在Windows平台这些库由微软提供,并且是以2种形式提供:静态库(lib)、动态库(lib+dll)。每个库还都提供debug、...
  • 一,异常的概念 Java异常类层次结构图: Throwable: 有两个重要的子类:Exception(异常...大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(V...
  • 各个版本Microsoft Visual C++运行时库下载 Microsoft Visual C++ 2005 Microsoft Visual C++ 2005 Redistributable Package (x86) https://www.microsoft.com/zh-cn/download/details.aspx?id=3387 Microsoft ...
  • 一.异常的概念 Java异常类层次结构图: Throwable:有两个重要的子类:Exception(异常...大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM (Java虚拟机)出现的问题。例如。Java虚拟机运行错误(Vi...
  • 五种常见的运行时异常

    千次阅读 2019-08-28 21:24:09
    五种常见的运行时异常 空指针异常 NullPointerException 数组越界异常 IndexOutOfBoundsException 类转换异常 ClassCaseException 向数组中存放与声明类型不兼容对象异常 ArrayStoreException ...
  • jdk11之后将javafx分离出来,使得用jdk11执行javafx时很容易出问题。 开发工具用idea,如果是使用jdk8的话很容易创建...1、错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序 2、或则是执行到fxml...
  • 什么叫编译时和运行时

    万次阅读 多人点赞 2018-06-17 15:02:22
    转载http://blog.csdn.net/weiwenhp/article/details/8107203以前经常听说编译时和运行时的概念.但没太搞明白具体代表啥意思.后面花了点时间研究了下.总算知道个大概意思了.编译时编译时顾名思义就是正在编译的时候....
  • 其中根据Exception异常进行划分,可分为运行时异常和非运行时异常。What:什么是检查异常(checked exception)?就是编译器要求你必须处置的异常。不知道你编程的时候有没有遇到过,你写的某段代码,编译器要求你必...
  • C++编译错误与运行时错误

    万次阅读 多人点赞 2018-06-22 09:51:31
    笔试题里经常会有这样的题目,让你判断运行时错误还是编译错误。在这里将它总结一下。 在调试过程中,运行时错误是最麻烦的问题。因为编译错误可以由编译器检查出来,而大多数编译器对运行时错误却无能为力。查错和...
  • JDK1.8关于运行时常量池, 字符串常量池的要点

    万次阅读 多人点赞 2018-11-29 22:53:13
    首先自行区分运行时常量池与Class文件常量池(静态常量池)的概念, JVM内存模型 ,方法区与永久代的区别, 有些在我的其他博客有介绍, 连接在文尾 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在...
  • 编译期常量与运行时常量

    千次阅读 多人点赞 2018-10-30 20:33:30
    编译期常量与运行时常量 1 前言 2 常量 2.1 编译期常量 2.2 运行时常量 2.3 对类的依赖性(了解) 3 编译时常量使用的风险 编译期常量与运行时常量 常量大家都不陌生,但如果你一听到这个词,脑袋里就只能想得...
  • JavaFX 11:“缺少JavaFX运行时组件”

    千次阅读 2019-12-13 14:35:40
    我正在尝试在Windows 10下使用jGRASP 2在JavaFX 11和Java 11下运行示例JavaFX代码(取自Java Illuminated的第五版). 我已经仔细阅读了“ JavaFX入门”指南(https://openjfx.io/openjfx-docs/),尽管取得了一些进步,...
  • 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。 受检异常跟程序运行的上下文环境有关,即使程序设计...
  • 看一个异常是运行时还是编译时异常,最简单的方法是看他的父类或者看他的爷爷、太爷爷...(开个玩笑)是不是RuntimeException。 比较通俗易懂的方法是,你把代码写出来之后,有红色波浪线提示你抛出或捕获异常,这...
  • 分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!... - ArithmeticException(算术异常) - ClassCastException (类转换异常) - IllegalArgumentException (非法参数...
  • java 运行时异常与非运行时异常理解

    万次阅读 2017-04-11 11:23:52
    java异常分为两种:运行时异常(RuntimeException)和非运行时异常(CheckedException)也叫检查式异常。 1.运行时异常是不需要捕获的,程序员可以不去处理,当异常出现时,虚拟机会处理。常见的运行时异常有空...
  • 在Java程序中打印java运行时参数

    万次阅读 2020-12-10 09:42:04
    在Java程序中打印java运行时参数 本文是基于CentOS 7.3系统环境,进行java的学习和使用 CentOS 7.3 1. java运行时参数 Java程序在运行时,主要分为两大类参数,一类是JVM参数,一类是Java程序main函数的输入参数 ...
  • 类似于用命令行运行时输入运行参数,IntelliJ 运行程序前设置运行参数
  • 原因:应用需要的dll与提供dll的.NET Framework版本不一致,比如应用需要的版本是.NET Framework2,但是本地提供的是.NET Framework 4。 可以使用ILSpy工具查看dll版本 ...
  • 其主要原因是 word启动自动加载的模板出现了问题 解决办法:将路径为 C:\user\(用户名)\AppData\Roaming\Microsoft\Word\Startup 下的文件全部删除即可。 ...
  • 解决MathType安装包在使用公式编辑器Math Type,有时候会遇到字体缺少或者其他一些情况,导致我们没办法正常使用编辑器,下面就来给大家介绍一下如何安装MT Extra字体问 MathType 安装出现问题,或者用久了之后...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,195,943
精华内容 2,478,377
关键字:

运行时