try-with-resources
这个特性是在JDK7中出现的,我们在之前操作一个流对象的时候大概是这样的:
try { // 使用流对象 stream.read(); stream.write(); } catch(Exception e){ // 处理异常 } finally { // 关闭流资源 if(stream != null){ stream.close(); } }
这样无疑有些繁琐,而且finally块还有可能抛出异常。在JDK7种提出了try-with-resources机制, 它规定你操作的类只要是实现了AutoCloseable接口就可以在try语句块退出的时候自动调用close 方法关闭流资源。
public static void tryWithResources() throws IOException { try( InputStream ins = new FileInputStream("/home/biezhi/a.txt") ){ char charStr = (char) ins.read(); System.out.print(charStr); } }
使用多个资源
try ( InputStream is = new FileInputStream("/home/biezhi/a.txt"); OutputStream os = new FileOutputStream("/home/biezhi/b.txt") ) { char charStr = (char) is.read(); os.write(charStr); }
当然如果你使用的是非标准库的类也可以自定义AutoCloseable,只要实现其close方法即可。
捕获多个Exception
当我们在操作一个对象的时候,有时候它会抛出多个异常,像这样:
try { Thread.sleep(20000); FileInputStream fis = new FileInputStream("/a/b.txt"); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
这样代码写起来要捕获很多异常,不是很优雅,JDK7种允许你捕获多个异常:
try { Thread.sleep(20000); FileInputStream fis = new FileInputStream("/a/b.txt"); } catch (InterruptedException | IOException e) { e.printStackTrace(); }
并且catch语句后面的异常参数是final的,不可以再修改/复制。
处理反射异常
使用过反射的同学可能知道我们有时候操作反射方法的时候会抛出很多不相关的检查异常,例如:
try { Class<?> clazz = Class.forName("com.biezhi.apple.User"); clazz.getMethods()[0].invoke(object); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
尽管你可以使用catch多个异常的方法将上述异常都捕获,但这也让人感到痛苦。 JDK7修复了这个缺陷,引入了一个新类ReflectiveOperationException可以帮你捕获这些反射异常:
try { Class<?> clazz = Class.forName("com.biezhi.apple.User"); clazz.getMethods()[0].invoke(object); } catch (ReflectiveOperationException e){ e.printStackTrace(); }