JDK7以后,一个catch里可以捕获多个类型的异常
catch (IOException|SQLException ex) {//这个时候ex自动变成final的 logger.log(ex); throw ex; }
finally块的内容即使在你意外提交了return
,continue
,break,依然会确保执行
但如果在try中终止了JVM,或者是执行线程被中断,被终止,当然无法执行
如果try和finally同时跑出了异常,则try中的会被埋名,方法最终会抛出finally的异常
JDK7以后,有了这种try-with语句
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
try的括号里声明的资源必须实现了java.lang.AutoCloseable接口,这个接口也是JDK7新加的
AutoCloseable有很多子接口,如java.io.Closeable,实现了这个也可以
try-with中可以有多个变量声明及定义,但最后一个没有分号,最终会以反序调用他们的close()
最后也可以跟个finally块,但会在try-with的资源关闭后才会进入finally块
如果try和try-with中同时跑出了异常,则try-with中的会被埋名,方法最终会抛出try的异常
JDK7以后可以调用Throwable.getSuppressed得到被埋名的异常
java.util.logging可以记录异常信息到文件
try { Handler handler = new FileHandler("OutFile.log"); Logger.getLogger("").addHandler(handler); } catch (IOException e) { Logger logger = Logger.getLogger("package.name"); StackTraceElement elements[] = e.getStackTrace(); for (int i = 0, n = elements.length; i < n; i++) { logger.log(Level.WARNING, elements[i].getMethodName()); } }
通常来说,不要手动抛出运行时异常,也不要生成他们的子类,那是自找麻烦
再就是,如果某个异常你的确能够处理,那么就声明为检查异常
以下情形会体现出异常的优势:
1.多个方法都有某种判断,可以写在一块,多个catch,逻辑清晰
2.将错误处理部分,按调用链上移,代码能够良好的组织
3.异常的分类详细,不够用还可以自定义