【问题标题】:Java decompiled code meaningJava反编译代码含义
【发布时间】:2011-07-19 23:19:12
【问题描述】:

我最近反编译了一些 Java 代码,但部分的语法我不明白。我已经搜索过这个,但我看到的许多线程都说与此类似的代码取决于编译器。在 java 语法检查中,这会返回错误。

public void run()
    {
        try
        {
            final InputStream inputSocketInputStream = inputSocket.getInputStream();
            final OutputStream inputSocketOutputStream = inputSocket.getOutputStream();
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(APJP.APJP_LOCAL_HTTP_SERVER_ADDRESS, APJP.APJP_LOCAL_HTTP_SERVER_PORT));
            final InputStream outputSocketInputStream = socket.getInputStream();
            final OutputStream outputSocketOutputStream = socket.getOutputStream();
            Thread thread = new Thread() {

                final InputStream val$inputSocketInputStream;
                final OutputStream val$outputSocketOutputStream;
                final HTTPProxyServerWorker this$0;

                public void run()
                {
                    try
                    {
                        byte abyte0[] = new byte[5120];
                        for(int i = 0; (i = inputSocketInputStream.read(abyte0)) != -1;)
                        {
                            outputSocketOutputStream.write(abyte0, 0, i);
                        }

                        outputSocketOutputStream.close();
                    }
                    catch(Exception exception1) { }
                }


            {
                this$0 = HTTPProxyServerWorker.this;
                inputSocketInputStream = inputstream;
                outputSocketOutputStream = outputstream;
                super();
            }
            };
            thread.start();
            /** OMITTED **/
    }

我对这一点感到困惑:

Thread thread = new Thread() {

                final InputStream val$inputSocketInputStream;
                final OutputStream val$outputSocketOutputStream;
                final HTTPProxyServerWorker this$0;

                public void run()
                {
                    try
                    {
                        byte abyte0[] = new byte[5120];
                        for(int i = 0; (i = inputSocketInputStream.read(abyte0)) != -1;)
                        {
                            outputSocketOutputStream.write(abyte0, 0, i);
                        }

                        outputSocketOutputStream.close();
                    }
                    catch(Exception exception1) { }
                }

            //WHAT IS THIS BELOW? Constructor?
            {
                this$0 = HTTPProxyServerWorker.this; 
                inputSocketInputStream = inputstream;
                outputSocketOutputStream = outputstream;
                super();
            }
            };

谁能解释一下这段代码应该如何工作?

【问题讨论】:

  • @matt b:但是假设输入和输出流是在外部块中定义的(可能是真的),这是完全有效的 java。
  • @Voo - val$inputStream 是一个有效的标识符,但 $ 没有特殊含义 - 所以反编译器产生未初始化的声明很奇怪,除非这里只是省略了赋值。然而,更大的一点是存在的。

标签: java decompiling


【解决方案1】:

这是non static initialization block。反编译器在非编译源中转换字节码是很常见的。恕我直言,最佳代码由 JD Decompiler 生成。这个变量

            final InputStream val$inputSocketInputStream;
            final OutputStream val$outputSocketOutputStream;
            final HTTPProxyServerWorker this$0;

是从非静态内部类访问最终局部变量的解释。变量this$0 引用包含内部类实例的外部类实例。在这种情况下,内部类是匿名的,因此存在初始化块而不是构造函数。可以说带有$的变量是编译器生成的。事实上,这是反编译器对字节码的解释。

【讨论】:

  • 那么这里的 val$ 是什么意思?我可以看到在初始化块中定义了 this$0,但是如何定义 val$?通过编译器?那么外部类中应该 val$inputSocketInputStream = inputSocketInputStream 吗?
  • val$ 只是整个标识符的一部分。变量 val$inputSocketInputStream 链接到最终静态变量,因此匿名内部类可以访问它。编译器在这里迷失了一点。由于名称冲突,添加了 val$。是的,在初始化块中应该有 val$inputSocketInputStream = inputstream;
  • 那么这是否意味着 val$inputSocketInputStream 是指向第 5 行定义的最终静态变量 inputSocketInputStream 的链接?
  • 要清楚,变量名中的$没有特殊含义。 $ 是在符号名称中使用的有效字符,它很少使用(而且几乎总是表明某些东西是自动生成的)。
【解决方案2】:
{
  this$0 = HTTPProxyServerWorker.this; 
  inputSocketInputStream = inputstream;
  outputSocketOutputStream = outputstream;
  super();
}

此块初始化内部类隐式变量。

假设您声明一个具有(非静态)内部类的类:

public class Outter {
  private int a = 1;

  class Inner {
    void doSomethingToOutter() {
      a += 1;
    }
  }
}

Inner 类将在构造 Outter 时隐式获取将初始化为 this 的其他成员。尝试反编译这个示例,看看你会得到什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多