JavaSE学习Day10之异常学习
异常:在写代码时会出现的一些意料之外的情况
1· 异常的划分(分类):
所有的异常的直接或间接父类是 Throwable
异常的两大子类: Exception( 可以处理的异常) , Error( 不可处理的错误(异常) )
检查型异常(Check Exception): Throwable 和 Exception以及它的子类
必须进行 try-catch 或者 throws 处理的异常,否则就会报错
非检查型异常(Uncheck Exception): Error 和 RuntimeException 以及它们的子类,
这类异常在编译时可以不用进行任何的处理仍可通过编译
2·异常的处理:
1)积极处理异常:
try{
//可能会发生异常的代码
} catch( 发生异常的类型 异常对象 ){
//处理异常的代码
}
2)消极处理异常: throw 异常对象 / throws 异常类型名
throws : 如果一个方法没有使用 try-catch 来处理异常,那么异常发生时,
会将异常对象传递给这个方法的调用者,这时候需要在方法声明上列出可能抛出的异常
main 的调用者是 JVM ,当异常传给 JVM 时,程序运行就结束了
throw: 主动抛出异常,程序员手动抛出发生的异常对象,throw之后就不再执行之后的代码,跳转到异常处理流程里
在方法声明上或者在方法内将异常抛出
例: public static void main(String[] args) throws 异常类型1,异常类型2... {
thorw new 异常对象(); //只能是Exception或是Error的子类对象
}
注意:
1)当发生的异常是检查型异常( Check Exception )时, 必须对该异常进行处理,要么 try - catch ,要么 throws ,必须二选一
2)可以用catch捕获多个异常,catch块的顺序: 如果既有子类异常,又有父类异常,那么子类异常必须在父类异常的前面
3)JDK1.7之后catch捕获的异常中可以是多个平级异常
3·异常的相关方法:
getMessage(): 获取异常信息
printStackTrace: 打印异常的跟踪信息
4·异常使用的注意:
1)不用吞掉异常,即捕获到异常后要对异常进行处理,以便我们自己能知道程序哪里出现了问题,方便处理
2)与有返回值的方法连用时, 要么在 catch块里添加 return 语句,或者将该异常 throw 抛出去
例:
public class Exception5 {
public static int test(){
try {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int r = 1/n;
return r;
} catch (Exception e ) {
System.out.println(e.getMessage());
return -1; // 解决方法1: 在catch也写一个return返回结果
throw e; // 解决方法2: 把异常重新抛出
}
}
public static void main(String[] args) {
int r = test();
System.out.println(r);
}
}
3)( throws ) 针对于检查型异常 : 重写方法时 子类要么不抛出异常,要么就抛出比父类级别更小的异常
而针对于 非检查型异常 时,不用遵守该规定;
4) 在开发时,通常会将 检查异常 转换为 非检查异常 进行处理,简化代码,减少复杂代码
例:
try{
...
}catch( IOException e ){
throw new RuntimeException(e); // 检查异常 ---> 非检查异常
}
5 finally: 里面放着的是程序无论是否发生错误都要执行的代码块
格式:
try{
}catch(){
}finally{
// 无论是否发生异常,总是要执行的代码 : 一般是一些关闭资源,释放资源的代码
}
注意:
1)如果 try-catch语句里出现了 return 语句,finally里面也有 return 语句,那么执行的是finally里的 return 语句
2)如果 try 语句中有return语句,但finally中对返回值做了修改,这时不会影响try中的 return语句,
它依然返回 finally修改之前的结果,( 因为在finally修改之前,已经将 return中的返回值进行了保存,
所以不论怎么修改,返回的结果依然是保存的那个结果)