4

我最近安装了字节码大纲 Eclipse 插件,发现我的测试类

public class Test {
}

调用 java.lang.Object 的构造函数

public class Test {
  public <init>()V
   L0
    LINENUMBER 15 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init>()V
    RETURN
   L1
    LOCALVARIABLE this LTest; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1
}

INVOKESPECIAL java/lang/Object.<init>()V 表示调用 java.lang.Object 的构造函数

这有什么意义吗?通过 java.lang.Object 字节码判断

  public <init>()V
   L0
    LINENUMBER 37 L0
    RETURN
    MAXSTACK = 0
    MAXLOCALS = 1

它什么也没做。刚回来。

4

2 回答 2

4

为了满足JVM 规范中关于结构约束的第 4.9.2 节,它必须:

每个实例初始化方法(第 2.9 节),除了派生自类 Object 的构造函数的实例初始化方法外,必须在访问其实例成员之前调用 this 的另一个实例初始化方法或其直接超类 super 的实例初始化方法。

现在,对于直接子类的类,可以放宽Object规则- 但我怀疑它是否有任何好处,并且会不优雅(IMO)。如果Object构造函数将来确实执行了一些初始化怎么办?你真的想要一个允许你绕过它的规范吗?

于 2012-12-07T16:26:15.007 回答
3

Java 编译器不应java.lang.Object区别于任何其他可能具有更复杂的默认构造函数的基类。因此,基类的构造函数必须从任何子类的构造函数中执行。该字节码对于将来修改基类(包括 )也是安全的Object:如果有一天有人更改了基类,则不应重新编译子类的代码。

BTW changes in base class including Object are not so exotic: think about instrumentation packages. If you want to instrument the JDK and for example count all created object you want to modify byte code of java.lang.Object. Now, if byte code does not contain invocation of Object constructor your instrumented code just will not run.

于 2012-12-07T16:28:25.253 回答