概念
Throwable类,只有Throwable类的实例才可以抛出或者捕获,它是Java异常处理机制的基类,Exception和Error都继承与它。Exception和Error是Java对于异常处理的两种方式,只是在具体使用场景和功能上有所差别。
Exception
Exception是java程序运行中可预料的异常情况,可以获取到这种异常,并且对这种异常进行业务外的处理。分为检查性异常和非检查性异常。两个根本的区别在于,检查性异常 必须在编写代码时,使用try catch捕获(比如:IOException异常)。非检查性异常 在代码编写使,可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的。
Exception又分为可检查(checked)异常和不检查(unchecked)异常。可检查(checked)异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分,如FileNotFoundException。
不检查异常就是所谓的运行时异常,类似 NullPointerException、ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
Error
Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。
Exception和Error对比案例分析
NoClassDefFoundError和ClassNotFoundException的区别
二者的区别
区别一: NoClassDefFoundError它是Error,ClassNotFoundException是Exception。
区别二:还有一个区别在于NoClassDefFoundError是JVM运行时通过classpath加载类时,找不到对应的类而抛出的错误。ClassNotFoundException是在编译过程中如果可能出现此异常,在编译过程中必须将ClassNotFoundException异常抛出。
二者的发生场景区别
NoClassDefFoundError发生场景如下:
1、类依赖的class或者jar不存在
2、类文件存在,但是存在不同的域中
3、大小写问题,javac编译的时候是无视大小的,很有可能你编译出来的class文件就与想要的不一样
ClassNotFoundException发生场景如下:
1、调用class的forName方法时,找不到指定的类
2、ClassLoader 中的 findSystemClass() 方法时,找不到指定的类
Exception案例分析
try {
FileInputStream fileInputStream = new FileInputStream(file);
return 3;
} catch (FileNotFoundException e) {
//异常信息打印
e.printStackTrace();
}finally {
return 6;
}
java.io.FileNotFoundException: 234 (No such file or directory)
2019-05-26 11:49:19.850 4727-4727/? W/System.err: at java.io.FileInputStream.open(Native Method)
2019-05-26 11:49:19.850 4727-4727/? W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:146)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at com.hongzhen.testdemo.MainActivity.testException(MainActivity.java:25)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at com.hongzhen.testdemo.MainActivity.onCreate(MainActivity.java:17)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.Activity.performCreate(Activity.java:6679)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.ActivityThread.-wrap12(ActivityThread.java)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.os.Looper.loop(Looper.java:154)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6119)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2019-05-26 11:49:19.851 4727-4727/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
2019-05-26 11:49:19.852 4727-4727/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
2019-05-26 11:49:19.852 4727-4727/? I/Test: 6
这个方法返回的值是6
这个这个异常处理逻辑中,finally是终会执行的,finally的业务操作是在try业务操作的return返回调用者者之前执行。实际情况是,执行完try中的业务逻辑后,return返回的操作会先存储到一个临时的堆栈中,此时不给调用者返回,随后执行finally中的业务代码。如果finally中有return操作,那么就会把finally中的return值返回。