• try-with-resource机制的一个编译陷阱


      为了解决问题,偶然发现一个奇怪的地方:就是使用try-with-resource机制的代码编译后,使用jd-gui反编译文件出现// ERROR //,但是程序运行却是正常的

      进一步确认后发现:如果try语句中只有一个定义时,反编译后也不会报错(如果有两个可以嵌套try语句);而且编译完以后的代码跟正常的代码编译完后的差距很大。

    以下是测试证明:

     原始的写法举例

    public byte[] file2byte(String filePath) {
        byte[] buffer = null;
        File file = new File(filePath);
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        } catch (Exception e) {
            // e.printStackTrace();
        } finally{
            try {
                if(fis != null){
                    fis.close();
                }
                if(bos != null){
                    bos.close();
                }
            } catch (IOException e) {
                //e.printStackTrace();
            }
        }
        return buffer;
    }
    View Code

     反编译结果:

    public byte[] file2byte(String filePath) {
        byte[] buffer = null;
        File file = new File(filePath);
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                int n;
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        }
        catch (Exception localException)
        {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (bos != null)
                    bos.close();
            }
            catch (IOException localIOException)
            {
            }
        }
        finally
        {
            try
            {
                if (fis != null) {
                    fis.close();
                }
                if (bos != null)
                    bos.close();
            }
            catch (IOException localIOException1)
            {
            }
        }
        return buffer;
    }
    View Code

     反编译后部分截图:

    try语句中有两个定义的时候

    public byte[] file2byte(String filePath) {
        byte[] buffer = null;
        File file = new File(filePath);
        try (FileInputStream fis = new FileInputStream(file);
                ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        } catch (Exception e) {
            // e.printStackTrace();
        }
        return buffer;
    }
    View Code

     反编译结果:

    // ERROR //
      public byte[] file2byte(String filePath)
      {
        // Byte code:
        //   0: aconst_null
        //   1: astore_2
        //   2: new 725    java/io/File
        //   5: dup
        //   6: aload_1
        //   7: invokespecial 727    java/io/File:<init>    (Ljava/lang/String;)V
        //   10: astore_3
        //   11: aconst_null
        //   12: astore 4
        //   14: aconst_null
        //   15: astore 5
        //   17: new 728    java/io/FileInputStream
        //   20: dup
        //   21: aload_3
        //   22: invokespecial 730    java/io/FileInputStream:<init>    (Ljava/io/File;)V
        //   25: astore 6
        //   27: new 733    java/io/ByteArrayOutputStream
        //   30: dup
        //   31: invokespecial 735    java/io/ByteArrayOutputStream:<init>    ()V
        //   34: astore 7
        //   36: ldc_w 736
        //   39: newarray byte
        //   41: astore 8
        //   43: goto +13 -> 56
        //   46: aload 7
        //   48: aload 8
        //   50: iconst_0
        //   51: iload 9
        //   53: invokevirtual 737    java/io/ByteArrayOutputStream:write    ([BII)V
        //   56: aload 6
        //   58: aload 8
        //   60: invokevirtual 740    java/io/FileInputStream:read    ([B)I
        //   63: dup
        //   64: istore 9
        //   66: iconst_m1
        //   67: if_icmpne -21 -> 46
        //   70: aload 7
        //   72: invokevirtual 744    java/io/ByteArrayOutputStream:toByteArray    ()[B
        //   75: astore_2
        //   76: aload 7
        //   78: ifnull +26 -> 104
        //   81: aload 7
        //   83: invokevirtual 748    java/io/ByteArrayOutputStream:close    ()V
        //   86: goto +18 -> 104
        //   89: astore 4
        //   91: aload 7
        //   93: ifnull +8 -> 101
        //   96: aload 7
        //   98: invokevirtual 748    java/io/ByteArrayOutputStream:close    ()V
        //   101: aload 4
        //   103: athrow
        //   104: aload 6
        //   106: ifnull +85 -> 191
        //   109: aload 6
        //   111: invokevirtual 749    java/io/FileInputStream:close    ()V
        //   114: goto +77 -> 191
        //   117: astore 5
        //   119: aload 4
        //   121: ifnonnull +10 -> 131
        //   124: aload 5
        //   126: astore 4
        //   128: goto +17 -> 145
        //   131: aload 4
        //   133: aload 5
        //   135: if_acmpeq +10 -> 145
        //   138: aload 4
        //   140: aload 5
        //   142: invokevirtual 700    java/lang/Throwable:addSuppressed    (Ljava/lang/Throwable;)V
        //   145: aload 6
        //   147: ifnull +8 -> 155
        //   150: aload 6
        //   152: invokevirtual 749    java/io/FileInputStream:close    ()V
        //   155: aload 4
        //   157: athrow
        //   158: astore 5
        //   160: aload 4
        //   162: ifnonnull +10 -> 172
        //   165: aload 5
        //   167: astore 4
        //   169: goto +17 -> 186
        //   172: aload 4
        //   174: aload 5
        //   176: if_acmpeq +10 -> 186
        //   179: aload 4
        //   181: aload 5
        //   183: invokevirtual 700    java/lang/Throwable:addSuppressed    (Ljava/lang/Throwable;)V
        //   186: aload 4
        //   188: athrow
        //   189: astore 4
        //   191: aload_2
        //   192: areturn
        //
        // Exception table:
        //   from    to    target    type
        //   36    76    89    finally
        //   27    104    117    finally
        //   17    158    158    finally
        //   11    189    189    java/lang/Exception
      }
    View Code

     反编译后部分截图:

     

     

    每个try语句中有只有一个定义的时候

    public byte[] file2byte(String filePath) {
        byte[] buffer = null;
        File file = new File(filePath);
        try(FileInputStream fis = new FileInputStream(file);) {
            try(ByteArrayOutputStream bos = new ByteArrayOutputStream();){
                byte[] b = new byte[1024];
                int n;
                while ((n = fis.read(b)) != -1) {
                    bos.write(b, 0, n);
                }
                buffer = bos.toByteArray();
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }
        return buffer;
    }
    View Code

     反编译结果:

    public byte[] file2byte(String filePath) {
        byte[] buffer = null;
        File file = new File(filePath);
        try { Object localObject1 = null; Object localObject4 = null;
          Object localObject3;
          label197: 
          try { fis = new FileInputStream(file);
          }
          finally
          {
            FileInputStream fis;
            Object localObject5;
            Object localObject8;
            ByteArrayOutputStream bos;
            byte[] b;
            int n;
            int n;
            Object localObject7;
            localObject3 = localThrowable1; break label197; if (localObject3 != localThrowable1) localObject3.addSuppressed(localThrowable1); 
          }
        } catch (Exception localException1) {
        }
        return buffer;
      }
    View Code

     最后也能反编译成功,但是反编译的文件有点看不懂了,反编译后部分截图:

     

  • 相关阅读:
    【ci框架】ci框架目录结构分析
    php CI框架
    jQuery boxy弹出层插件中文演示及讲解
    Jenkins构建报错(Jenkins is reserved for jobs with matching label expression)解决办法
    redis缓存数据架构实战
    Git免密码pull&push
    Maven搭建Nexus私有仓库
    Windows使用filezilla搭建FTP服务器
    CentOS7.4使用yum安装MySQL5.6
    MySQL数据库连接池导致页面登录无法查询问题解决过程
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/tryTrap.html
Copyright © 2020-2023  润新知