java中关于资源的使用大家估计都不陌生,无非就是请求资源,建立连接,读取资源,关闭资源几个步骤,为了保证资源能够顺利释放,都是在finally块中进行资源释放,下面常见的资源访问实例:
public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream(""); } catch (FileNotFoundException e) { e.PRintStackTrace(); } finally { try { if(fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } }上面的代码 ,简单的功能需要的代码长且不说,而且不够优雅,在同时有输入流输出流的情况,将会更加复杂,异常处理难度令人抓狂。 现在我们可以摆脱这种现状了,java7新语法,提供自动关闭资源的方式,如下
public static void main(String[] args) { try (FileInputStream fis = new FileInputStream("");) { fis.read(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }仔细看,资源的连接是在try()中,这种新语法支持,凡是实现接口AutoCloseable的类都可以使用这种方式进行资源访问,并且会自动释放。 下面,我们仔细分析下,为什么资源会自动释放,我们看下面这段,是新 方式代码javap后的汇编,我简单的注释下:
public static void main(java.lang.String[]); Code: 0: aconst_null 1: astore_1 2: aconst_null 3: astore_2 4: new #16 // class java/io/FileInputStream 7: dup 8: ldc #18 // String 10: invokespecial #20 // Method java/io/FileInputStream."<init>":(Ljava/lang/String;)V 13: astore_3 //将实例化的FileInputStream对象引入保存到局部变量3中 14: aload_3 //FileInputStream引用入栈 15: invokevirtual #23 // Method java/io/FileInputStream.read:()I 18: pop 19: aload_3 20: ifnull 76 //资源为空,则表示没有开启资源,也成功返回 23: aload_3 //如果保存FileInputStream对象引用的变量不为空则关闭资源 24: invokevirtual #27 // Method java/io/FileInputStream.close:()V 27: goto 76 //成功返回 30: astore_1 //既然上面代码就能保证成功返回,此处开始的代码就是异常处理了 31: aload_3 32: ifnull 39 35: aload_3 36: invokevirtual #27 // Method java/io/FileInputStream.close:()V 39: aload_1 40: athrow 41: astore_2 42: aload_1 43: ifnonnull 51 46: aload_2 47: astore_1 48: goto 61 51: aload_1 52: aload_2 53: if_acmpeq 61 56: aload_1 57: aload_2 58: invokevirtual #30 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V 61: aload_1 62: athrow 63: astore_1 64: aload_1 65: invokevirtual #36 // Method java/io/FileNotFoundException.printStackTrace:()V 68: goto 76 71: astore_1 72: aload_1 73: invokevirtual #41 // Method java/io/IOException.printStackTrace:()V 76: return Exception table: //这是java异常处理的机制,维护异常表,根据表来查询异常后的跳转代码。 from to target type 14 19 30 any //当资源读时异常,跳到30处(内存偏移量)继续执行,可以看到是资源关闭的处理。 4 41 41 any 0 63 63 Class java/io/FileNotFoundException 0 63 71 Class java/io/IOException分析后发现,新的语法其实就是一种编译器优化,资源总会关闭,不管是否发生异常。人通常会犯错,但是编译器却不会,所以使用新的方式进行资源访问,能够避免隐藏的bug,而在java7中绝大多数的资源访问都已经重新实现了AutoCloseable接口,包括网络访问socket等,所以基本上可以放心的使用,就算没实现,编译器也会快速报错。
新闻热点
疑难解答