【问题标题】:Viewing code inserted by the Java compiler查看 Java 编译器插入的代码
【发布时间】:2015-11-01 12:55:03
【问题描述】:

Java 类文件可以反编译以显示编译器添加的所有代码吗?例如,只要找不到显式构造函数,Java 编译器就会插入一个无参数构造函数。但是,当我反编译没有显式构造函数的类文件时,编译器插入的类文件不会出现。另一个例子是编译器在任何没有明确扩展其他类的类中插入“扩展 java.lang.Object”。同样,当我反编译这样一个类时,我没有在反编译的文本中看到类声明的“扩展”组件。也许我认为 Java 编译器“插入”代码太字面意思了?也许我需要一个更复杂的反编译器?

【问题讨论】:

  • 考虑改为读取字节码。
  • 如果可以的话,我会要求任何反对票都附上解释性评论。即使在后来的审查之后,也并不总是很明显,为什么一个帖子可能不清楚、没有用,或者没有表现出在研究方面的努力,这是投反对票的标准。非常感谢。
  • 您认为如何处理“显示不努力研究”(我个人认为这是这里的问题,即使我没有投反对票)标准?

标签: java compilation


【解决方案1】:

最好使用来自asm 的字节码查看器作为 ASMifier。编译器添加的一些指令在反编译时会被跳过,以保持源代码和反编译的代码接近。

您将通过签名public <init>()V 找到默认构造函数。如果未定义构造函数,则将其添加到字节码中。

【讨论】:

  • 感谢 CoronA。你和 Thorbjørn 让我走上了正确的道路。使用字节码查看器,我确实看到了默认的无参数构造函数以及反编译器未显示的一堆其他代码。但是,我在作为 Object 的直接后代的类声明中没有看到“扩展 java.lang.Object”。我将此作为对您观察到某些代码是在运行时添加而不是由编译器添加的确认的确认。
  • "Some defaults... by the runtime" 语句不正确。
  • extends ArrayList 出现在字节码中,extends Object 没有。但是构造函数总是可以在字节码中找到。所以我更正了我的说法。
  • “(例如对象的默认继承)未写入”不正确。见docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1“如果super_class项的值为零,那么这个类文件必须代表类Object,唯一没有直接超类的类或接口。”
  • 我没有看到错误。除了 object 之外的每个超类都可以从字节码中直接读取(它的名称驻留在常量池中)。 java.lang.Object 类由 zero 表示,但您不会在字节码中找到它的名称。字节码查看器不显示此信息。当然,运行时解析是微不足道的(如果为零,则为 Object),但这种解码是在运行时完成的解释。
猜你喜欢
  • 2010-10-02
  • 2016-03-14
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
相关资源
最近更新 更多