参考书籍:Head First Java
1、假设某方法是别人写在某个类里面的
2、而此时你根本就不知道这个方法是否有风险(比如服务器出故障会使程序受到影响);
3、那最好的方法应该就是,在调用这个类的方法时,加上可能发生异常的处理方案,未雨绸缪。
关键字:try……catch,throws,throw,finally
try……catch其实就是给编译器的一个信号,表示你已经注意到了这个异常并开始着手进行应对;
编译器需要程序员try包裹住可能发生异常的代码,再通过catch去处理
RuntimeException被称为不检查异常,当然也可以try……catch,但编译器是不会管的;因为大部分的RuntimeException都是因为无法预估和避免的问题产生,无法保证文件一直都存在,无法保证服务器不会宕机,try……catch是为了确保程序不会运行不合理的逻辑,比如对只有5项元素的数组取第8个元素的值,该块要做的是恢复的尝试,至少也要友好的输出错误信息。
throws表示你在编写一段有异常的程序,可能有异常的方法必须通过throws进行声明,声明之后,异常会抛出给负责调用的代码;此时负责调用的代码就需要对异常进行处理,如果此时不使用try……catch进行处理,也可以使用throws进行抛出,这种行为在Java里被称作ducking,但这种行为只是在踢皮球,异常依然存在,抛到最后一层的时候,main函数也抛出的话,那就只能JVM来处理了,JVM和编译器是一伙的,所以肯定又会踢回给main函数,最终还是得处理。所以异常可以在方法中声明(throws抛出),不在方法中处理,而在调用的时候处理。
throw:使用throw自己创建Exception对象。比如:throw new Exception("a不等于11");在创建异常对象的同时自己添加异常信息
如果是使用throw,明显有Exception,此时就必须用throws抛出异常,当然即使只是可能有Exception的代码也需要用throws抛出异常。
finally表示不管是否有异常,都必须执行finally包裹的代码
finally和return同时出现的情况:如果在try当中出现了return,finally里的语句还是会被执行,而且是在return之前执行
finally唯一不会执行的情况:执行前程序已经退出(catch中有system.exit(1))
这里有一个函数:
public static void doRisky(String test) throws Exception { System.out.println("start risky"); if("yes".equals(test)){ throw new Exception(); } System.out.println("end risky"); return; }
在执行此方法的时候,是需要try……catch的:
try{doRisky("no");} catch (Exception e){System.out.println("Exception");e.printStackTrace();}
这里是否需要try……catch和传入的值是yes还是no没有关系,关键在于doRisky已经throws抛出了一个异常,所以你就必须在调用的时候catch并处理
这里关于finally的输出也要注意,有意思的是,如果传入的是yes,会先执行try当中的内容,catch之后再输出finally,但是在doRisky之后如果还有输出,就不会被执行了,因为发生了异常就会直接跳到catch部分,也就是说产生异常的那个方法之后的try部分都不会被执行,如果传入的是no,那结果就不一样了,try会被执行完
可以直接做错误输出,输出的字体是不一样的,getMessage()可以直接输出异常名称,和e.printStactTrace()不一样,后者输出的不只是名称,还有其他的详细信息
多种异常如果需要做针对性的处理,就要使用多个catch,使用多个catch时要注意:
把范围比较小的异常放在前面,就是说不能把父类异常放在子类异常的前面,就好像不能把大篮子放在小篮子上