典型的异常
错误Error:
StackOverflowError:方法递归调用,会发生栈内存溢出错误
OutOfMemoryError:当不断得向堆中创建对象时,会出现
异常Exception:
异常是可以捕捉住,然后让程序恢复运行
ArrayIndexOutOfBoundsExceptions:数组下标越界
NullPointerException:访问null的对象的方法或属性时
ClassCastException:类型转换失败时
ConcurrentModificationException:并发修改异常
ArithmeticException:除零异常
处理异常的方法
方法1.积极处理
try {
// 有可能出现异常的代码
} catch( 异常类型 ) {
// 捕获异常后的代码
}
注意: 1). catch能捕捉的异常,要么精确匹配,要么用父类型匹配
2).可以用多个catch捕获不同类型的异常
3).多个catch块时,子类的catch块要写在前面,父类要写在后面
4). 1.7 后一个catch块中可以有多个平级的异常
方法2. 消极处理
语法: 在方法的声明部分添加 throws 异常类型
含义: 说明方法在执行时有可能出现的异常,将异常交给方法的调用者处理
main 的调用者是jvm,当异常传给jvm时,程序运行就结束了
从异常的行为分类:
未检查异常(uncheck)
RuntimeException或它的子类
Error和它的子类
检查异常(check)
Throwable
Exception以及他们的子类
检查异常需要强制地配合try-catch或throws一起使用
主动抛出异常
throw new 异常对象()
异常对象的常见方法
e.getMessage() 获取异常的信息
e.printStackTrace() 打印异常的跟踪信息
自定义异常
创建异常类
class MyException extends Exception{ // 检查异常
}
class MyException extends RuntimeException { // 未检查异常
}
异常使用的经验
1) 不要吞掉异常
2) 与有返回值的方法连用时要注意:
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)
子类的重写方法,不能抛出比父类更多的异常(检查异常)
子类的重写方法,可以不抛出异常
若父类和子类方法throws都是未检查异常不用遵守上述约定
4) 建议将检查异常转换为未检查异常重新抛出
finally
语法:
try {
...
} catch(Exception e) {
...
} finally {
// 无论出现异常与否,总会被执行的代码
}
如果try catch 以及finally都出现了return语句, 以finally中的return为准
如果try 有return, 但finally中对返回的变量做了修改, 不会影响return的结果