标签:cti port aci 文件内容 编译 illegal 不难 sim []
通过前篇的《Java文件IO流的操作总结》,我们知道了基本输入输出流的使用方式,但是每次都需要在finally处关闭流资源,这样操作起来既啰嗦又麻烦,有没有更简洁的方式呢?本篇就来讲解jdk1.7引入的try with resources语法糖式写法。
待读取的文件内容
示例代码
package com.lingyejun.io; import java.io.*; /** * Created by Lingye on 2018/9/28 15:03 */ public class SyntacticSugarTry { // 调用有finally的case值 public static final int OLD_TRY = 1; // 调用新式语法糖式的case值 public static final int SUGAR_TRY = 2; /** * 根据输入参数执行不同方法 * * @param type * @return */ public InputStream invokeTry(int type) { InputStream inputStream = null; switch (type) { case OLD_TRY: inputStream = oldTryCatch(); break; case SUGAR_TRY: inputStream = newTryCatch(); break; default: System.out.println("error type"); } return inputStream; } /** * 采用旧式的finally写法 * * @return */ public InputStream oldTryCatch(){ // 构建文件对象 File inputFile = new File("D:\\input.txt"); // 初始化输入流 InputStream inputStream = null; try { // 创建字节输入流 inputStream = new FileInputStream(inputFile); // 读取到1KB字节数组中 byte[] buffer = new byte[12]; // 读取数据并放到buffer数组中 inputStream.read(buffer); System.out.println("oldTryCatch读取输出"+new String(buffer)); } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { // 关闭流过程,也有可能出现异常 inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return inputStream; } /** * 采用语法糖式写法 * * @return */ public InputStream newTryCatch() { // 构建文件对象 File inputFile = new File("D:\\input.txt"); // 初始化输入流 InputStream returnStream = null; // try with resource 语法糖式写法 try (InputStream inputStream = new FileInputStream(inputFile)) { byte[] buffer = new byte[12]; inputStream.read(buffer); System.out.println("newTryCatch读取输出"+new String(buffer)); returnStream = inputStream; } catch (Exception e) { e.printStackTrace(); } // 省略了繁琐的finally return returnStream; } public static void main(String[] args) { SyntacticSugarTry sugarTry = new SyntacticSugarTry(); InputStream oldStream = sugarTry.invokeTry(OLD_TRY); InputStream sugarStream = sugarTry.invokeTry(SUGAR_TRY); // 检查流是否正常关闭 try { // 再次尝试读取,检查是否关闭 oldStream.read(); } catch (IOException e) { // 已关闭 System.out.println("oldStream 输入流已关闭"); } try { // 再次尝试读取,检查是否关闭 sugarStream.read(); } catch (IOException e) { // 已关闭 System.out.println("sugarStream 输入流已关闭"); } } }
查看文件管道的关闭情况
语法糖式写法,执行完毕后自动关闭输入流
查看输出结果
不难看出,语法糖的使用其实就是让我们的写的代码更简单,看起来也更容易理解。
语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了。这些语法糖虽然不会提供实质性的功能改进,但是它们或能提高性能、或能提升语法的严谨性、或能减少编码出错的机会。
使用JD-GUI打开上面类的.class编译文件后会发现编译过后,编译器给我们自动加上了资源流的close关闭动作(81行95行)。
/* Error */ public InputStream newTryCatch() { // Byte code: // 0: new 49 java/io/File // 3: dup // 4: ldc 51 // 6: invokespecial 53 java/io/File:<init> (Ljava/lang/String;)V // 9: astore_1 // 10: aconst_null // 11: astore_2 // 12: aconst_null // 13: astore_3 // 14: aconst_null // 15: astore 4 // 17: new 55 java/io/FileInputStream // 20: dup // 21: aload_1 // 22: invokespecial 57 java/io/FileInputStream:<init> (Ljava/io/File;)V // 25: astore 5 // 27: bipush 12 // 29: newarray <illegal type> // 31: astore 6 // 33: aload 5 // 35: aload 6 // 37: invokevirtual 60 java/io/InputStream:read ([B)I // 40: pop // 41: getstatic 29 java/lang/System:out Ljava/io/PrintStream; // 44: new 64 java/lang/StringBuilder // 47: dup // 48: ldc 102 // 50: invokespecial 68 java/lang/StringBuilder:<init> (Ljava/lang/String;)V // 53: new 69 java/lang/String // 56: dup // 57: aload 6 // 59: invokespecial 71 java/lang/String:<init> ([B)V // 62: invokevirtual 74 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder; // 65: invokevirtual 78 java/lang/StringBuilder:toString ()Ljava/lang/String; // 68: invokevirtual 37 java/io/PrintStream:println (Ljava/lang/String;)V // 71: aload 5 // 73: astore_2 // 74: aload 5 // 76: ifnull +55 -> 131 // 79: aload 5 // 81: invokevirtual 87 java/io/InputStream:close ()V // 84: goto +47 -> 131 // 87: astore_3 // 88: aload 5 // 90: ifnull +8 -> 98 // 93: aload 5 // 95: invokevirtual 87 java/io/InputStream:close ()V // 98: aload_3 // 99: athrow // 100: astore 4 // 102: aload_3 // 103: ifnonnull +9 -> 112 // 106: aload 4 // 108: astore_3 // 109: goto +15 -> 124 // 112: aload_3 // 113: aload 4 // 115: if_acmpeq +9 -> 124 // 118: aload_3 // 119: aload 4 // 121: invokevirtual 104 java/lang/Throwable:addSuppressed (Ljava/lang/Throwable;)V // 124: aload_3 // 125: athrow // 126: astore_3 // 127: aload_3 // 128: invokevirtual 82 java/lang/Exception:printStackTrace ()V // 131: aload_2 // 132: areturn // Line number table: // Java source line #75 -> byte code offset #0 // Java source line #77 -> byte code offset #10 // Java source line #79 -> byte code offset #12 // Java source line #80 -> byte code offset #27 // Java source line #81 -> byte code offset #33 // Java source line #82 -> byte code offset #41 // Java source line #83 -> byte code offset #71 // Java source line #84 -> byte code offset #74 // Java source line #85 -> byte code offset #127 // Java source line #88 -> byte code offset #131 // Local variable table: // start length slot name signature // 0 133 0 this SyntacticSugarTry // 9 13 1 inputFile java.io.File // 11 121 2 returnStream InputStream // 13 1 3 localObject1 Object // 87 16 3 localObject2 Object // 108 17 3 localObject3 Object // 126 2 3 e Exception // 15 1 4 localObject4 Object // 100 20 4 localThrowable Throwable // 25 69 5 inputStream InputStream // 31 27 6 buffer byte[] // Exception table: // from to target type // 27 74 87 finally // 17 100 100 finally // 12 126 126 java/lang/Exception }
参考文章:
https://www.cnblogs.com/jiumao/p/7136369.html
https://blog.csdn.net/Merlin2017/article/details/78075206
标签:cti port aci 文件内容 编译 illegal 不难 sim []
原文地址:https://www.cnblogs.com/lingyejun/p/9744604.html