异常 Exception
概述:异常就是Java程序运行过程中出现的错误
异常由来:现实生活有许多问题,可以通过Java形式对其进行描述,并封装成对象。 异常其实就是Java对不正常情况描述后的对象体现.
-
异常的处理方式
- JVM的默认处理
- try ... catch ... finally
- throws
异常的分类
Throwable
|-- Error (天灾人祸) StackOverflowError, OutOfMemoryError (JVM的异常) --> 1
|-- Exception
|-- 其他子类 编译期异常(受检查异常) --> 2
|-- RuntimeException 运行时异常(非受检查异常) --> 3
(一般出现第三种情况,都是代码不够严谨导致,所以推荐修改代码逻辑解决)
多个异常的情况
1. 对于每一个异常都单独处理
2. 一次进行处理
注意事项:
1. java的异常处理机制,如果在try代码块里面发生了异常,那try后面就不会被执行.
2. 如果发生异常,异常对象会依次和catch语句进行匹配,
如果匹配到到了,就执行对应的catch语句,如果没有,问题就不会得到处理。
catch语句只会执行一个
3. 异常类型如果是不兼容的,谁先谁后没有关系,如果有兼容关系,父类应该位于子类后面。
JDK7的新特性
在开发中,往往会对不同的异常进行同样处理
catch (ArrayIndexOutOfBoundsException | ArithmeticException e)
注意事项:
catch语句里面不能存在子父类关系,它们异常类型不能兼容
throws:
定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。
运行时异常:如果抛出的是运行时异常,上级可以处理也可以不处理
编译期异常:如果抛出的是编译期异常,上级必须处理throw:
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
throws 和 throw之间的区别:
throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示该方法可能抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的是一个具体的异常对象
只能抛出一个异常
表示抛出异常,由方法体内的语句处理(一般情况,方法会直接抛给上一级)
throw则是抛出了异常,执行throw则一定抛出了某个异常
异常处理的原则:
1. 如果异常该方法能够处理,那就自己处理 (及早处理)
如果异常后面的代码还要执行,只能自己处理
2. 如果自己处理不了就往上抛
如果异常后面的代码不需要执行,就可以往上抛
- try语句
try...catch...finally
try...catch
try...finally
try...catch...catch...
try...catch...catch...finally
finally:
被finally控制的语句体一定会执行
特殊情况:在执行到 finally 之前 jvm 退出了(比如System.exit(0))
作用:
用于释放资源,在IO流操作和数据库操作中会见到
面试题:
final,finally和finalize的区别
final:
修饰类:该类不能被继承
修饰变量:自定义常量
修饰方法:该方法不能被重写
finally:
和try语句一起使用,finally里面的语句一定会被执行,用于释放资源。
finalize():
定义在Object的一个方法,当垃圾回收器回收该对象时,会自动调用该对象的finalize方法。
如果catch里面有return语句,请问finally的代码还会执行吗? 返回的结果是多少?
会。 其实finally的代码是在return 中间执行。
1. 执行第一次return语句的时候,其实就已经生成返回路径,里面的值就是30;
2. 如果finally语句也有return语句,它就新生成了一条返回路径,里面的值就是40;
自定义异常
自定义异常:
a. 继承Exception: 编译期异常
继承RuntimeException: 运行时异常
b. 提供构造方法
MyException();
MyException(String message);
-
异常的注意事项:
子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。
如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能
try,不能throws
(针对编译期异常)子类不能比父类更坏,一代更比一代强
Throwable类
Throwable:
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,
才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的
参数类型。
构造方法:
Throwable()
构造一个将 null 作为其详细消息的新throwable。
Throwable(String message)
构造带指定详细消息的throwable。
成员方法:
String getMessage()
返回此 throwable 的详细消息字符串。
String toString()
返回此 throwable 的简短描述。
void printStackTrace()
将此 throwable 及其追踪输出至标准错误流(红色)。
// void printStackTrace(PrintStream s) // 日志文件 IO流
问题1:变量e没有赋值,为什么能够直接使用,为什么不报空指针异常呢?
如果try语句里面出现异常,JVM会把它封装对应异常类型的对象,然后依次和catch语句进行匹配,
如果匹配上了就会把该对象赋值给e;