try catch finally执行顺序
1.当语句块中没有return的时候,执行顺序为try,catch,finally
2.当try或者catch中有return或者throw的时候,finally永远在try中或者catch的return之前执行。
其实更加可以理解为:finally是在执行离开该代码块的语句之前执行。return和throw都是离开该try代码块的代码。
鉴于finally的执行情况会出现异常丢失
所以finally一般仅用于关闭IO流等。
try {
try {
throw new VeryImportantException();
} finally {
throw new HoHumException();
}
}catch (Exception e){
e.printStackTrace();
}//丢失VeryImportantException
try{
throw new Exception();
}finally{
return;
}//直接在finally返回而不捕获exception;
一、异常处理
抛出异常如果不进行强制处理,程序就终止,而try catch语句块则是对异常进行捕获处理,使程序回到正确的运行轨道
以前对异常感到很模糊,最简单的一个数组都会有越界异常,但是这个数组却不强制使用try catch 语句块来处理,而很多IO的都带了throws关键字,需要强制catch异常,之前感觉很费解。
而事实是异常太多,不可能一个一个去catch,写代码的时候应该尽量去避免一些低级的异常出现(看到后面才知道,都归类到RuntimeException了),或者手动throw抛出异常而避免try catch(比如abstractList中的add,set等方法都是“always throws an UnsupportedOperationException ”)。而throws只是一个异常声明,表明这个方法中有某个异常必须强制检查一遍。
二、记录日志
虽然现在用的是log4j,但是其实Java有自带的log工具(虽然书上给的logging介绍网站已经没有了)。那么这里提供一个介绍log4j使用blog。详细的Log4j使用教程。
三、异常类
3.1自定义异常只要继承exception类就好了。自定义的异常类最重要的其实是名字,其他方面记本可以super父类就好了。
3.2异常的重新抛出(感觉没啥用啊,大约是省资源),在catch块中抛出一个新异常,则外面的try catch块中捕获的异常就不同于原生异常,emmm其实就是可以一层一层的扒异常
3.3异常链
弥补重新抛出异常的时候信息无法保存的弊端,就是会在异常中声明cause by。其实就是抛出异常的时候在initCause()方法中加入之前异常信息
//exception是没有传入cause的构造器的,所以需要调用到initCause()方法
DynamicFieldsException dynamicFieldsException = new DynamicFieldsException();
dynamicFieldsException.initCause(new NullPointerException());
throw dynamicFieldsException;
其实这个模样的异常在框架的使用中常见如下是spring boot抛出一个thymeleaf模板parse的异常:
api介绍
throwable是exception和error的基类。
StackTraceElement[] getStackTrace();
就是异常抛出到调用所经过的方法名字的一个数组。
printStackTrace();
printStackTrace(PrintStream);
printStackTrace(PrintWriter);
打印方法调用出直到异常抛出处的方法调用序列,根据参数可以将信息输出到标准错误或者输出到想好的I/O流;
getMessage();getLocallizedMessage();这两个,emm很明了的名字了。
fillInStackTrace();记录throwable对象内部当前状态