Java反编译代码的含义

Java反编译代码的含义,java,decompiling,Java,Decompiling,我最近反编译了一些Java代码,但部分代码的语法我不懂。我已经搜索过了,但是我看到的很多线程都说类似的代码依赖于编译器。在java语法检查中,这将返回错误 public void run() { try { final InputStream inputSocketInputStream = inputSocket.getInputStream(); final OutputStream inputSocke

我最近反编译了一些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();
            }
            };
有人能解释一下这段代码是如何工作的吗?

这是。反编译器通常在非编译源代码中转换字节码。最好的代码是由JD反编译器生成的。这个变量

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

{
  this$0 = HTTPProxyServerWorker.this; 
  inputSocketInputStream = inputstream;
  outputSocketOutputStream = outputstream;
  super();
}
此块初始化内部类隐式变量

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

public class Outter {
  private int a = 1;

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

内部
类将隐式地获得额外的成员,这些成员将在构建
外部
时初始化为
。尝试反编译此示例,看看您得到了什么。

那么这里的val$是什么意思?我可以看到在初始化块中定义了$0,但是如何定义val$?通过编译器?那么val$inputSocketInputStream=inputSocketInputStream是否应该在外部类中?val$只是整个标识符的一部分。变量val$inputSocketInputStream链接到最终的静态变量,以便匿名内部类可以访问它。编译器在这里有点迷路了。由于名称Confirct,添加了val$。是的,在初始化块中应该有val$inputSocketInputStream=inputstream;那么这是否意味着val$inputSocketInputStream是第5行定义的最终静态变量inputSocketInputStream的链接?要清楚,变量名称中的
$
没有特殊含义
$
是符号名中使用的有效字符,它很少使用(几乎总是自动生成的符号)。@matt b:但假设输入和输出流在外部块中定义(假定为真)这是完全有效的java。@Voo-
val$inputStream
是一个有效的标识符,但是
$
没有特殊的含义-所以反编译器生成未初始化的声明是很奇怪的,除非这里省略了赋值。然而,更重要的一点仍然存在。