异常处理
什么是异常
当JVM执行程序是出现了某个异常时,就会实例化对应的异常实例并将其抛出.此时虚拟机会检查报错的这句代码是否有被异常处理机制处理,如果没有则会继续将该异常抛出到当前方法之外(比如这里会抛出到main方法之外) 如果异常最终被抛出到main方法意味着当前程序就结束了.
控制台上的异常信息: 异常的类型(通过它判断程序出现了什么问题)
Exception in thread "main" java.lang.NullPointerException
at 某包.某包....(某类.java:xx) <-第一行是实际报错的代码(后期开发不是我们自己写的代码)
at 某包.某包....(某类.java:xx) <-第二行如果存在,说明是它调用的上面第一行的方法,导致该方法报错,并且抛给了这里
at 某包.某包....(某类.java:xx)
at 某包.某包....(某类.java:xx)
at 某包.某包....(某类.java:xx)
at 某包.某包....(某类.java:xx)
at 某包.某包....(某类.java:xx)
at 某包.某包....(某类.java:xx)
at exception.TryCatchDemo.main(TryCatchDemo.java:17) <-当看到我们写的包和类时,就应当从这里开始排错,在哪个方法的第几行出现的错误
异常的处理
语法:
try{
可能出现异常的代码片段(A计划)
}catch(XXXException e){
try中出现XXXException后的处理代码(B计划)
}
代码实例
注意下面的演示代码出现的空指针以及下标越界异常都为可以避免的异常或者说出现这种异常是由于自己代码存在bug,因此在正式开发中若出现这种异常应该修改代码而不是使用这种方法来避免异常,异常处理应该是在明知道会发生但是无法避免的异常出现时才使用,例如:断网,或者硬件出现问题时
System.out.println("程序开始了");
try {
// String line = null;
// String line = "";
String line = "a";
System.out.println(line.length());
System.out.println(line.charAt(0));
System.out.println(Integer.parseInt(line));
} catch (NullPointerException | StringIndexOutOfBoundsException e) {
System.out.println("出现了空指针或下标越界的统一处理手段!");
//捕获一个超类型异常时,try中出现它的子类型异常都可以被其捕获
//多个catch存在继承关系时,子类型在上先捕获.超类在下后捕获.
//上面的catch捕获异常后,下面的catch就不执行了
} catch (Exception e) {
System.out.println("反正就是出了个错");
}
System.out.println("程序结束了");
finally块
finally简介
finally块是异常处理机制中的最后一块.它可以直接跟在try之后或者最后一个catch之后
finally的特点:只要程序执行到try当中,无论try中的代码是否出现异常,最终都要执行finally中的代码
通常使用finally用于完成资源释放这类操作,比如IO后的关闭操作.
代码实例
System.out.println("程序开始了");
try {
// String line = null;
String line = "abc";
System.out.println(line.length());
return;
//当try中某句代码出现异常后,try中剩余代码就不会被执行了
//try中就算执行到return,也要在结束方法前先走完下面的finally
} catch (NullPointerException e) {
System.out.println("出现空指针异常");
} catch (Exception e) {
System.out.println("出现异常");
} finally {
System.out.println("finally中代码执行了");
}
System.out.println("finally中代码执行了");
System.out.println("程序结束了");
案例
在前面的学习中,例如io中出现异常我们通常都是将他throw,这其实是不正确的操作,我们应该像上面一样去处理这个异常,具体实现看代码。
public static void main(String[] args) {
// 自动生成try-catch的快捷键ctrl+alt+t
FileOutputStream fos = null;
try {
fos = new FileOutputStream("fos.dat");
fos.write(1);
} catch (IOException e) {
System.out.println("出错了");
throw new RuntimeException(e);
} finally {
try {
if (fos == null) {//判断对象是否为null
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
JDK7之后,java推出了一个新的特性:自动关闭特性 可以在异常处理机制中更优雅的关闭流这类需要调用close关闭的类(io)
try (
// try()中可以定义最终要在finally中调用close的那些类
// 实际上只有实现了java.io.AutoCloseable接口的类才可以在这里定义
// java中所有的流都实现了AutoCloseable接口
// 该特性是编译器认可的,最终在try()中定义的类会在finally中被调用close关闭,相当于FinallyDemo2的样子
FileOutputStream fos = new FileOutputStream("fos.dat");
) {
fos.write(1);
} catch (IOException e) {
throw new RuntimeException(e);
}