是否真的需要调用java.lang.Object构造函数?

时间:2012-12-07 16:21:15

标签: java

我最近安装了字节码大纲Eclipse插件并发现了我的Test类

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
它什么都不做。只是回来。

2 个答案:

答案 0 :(得分:4)

必须满足结构约束的JVM规范的section 4.9.2

  

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

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

答案 1 :(得分:3)

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

包括Object在内的基类的BTW变化并不那么奇特:考虑一下仪器包。如果要对JDK进行检测,例如计算所有已创建的对象,则需要修改java.lang.Object的字节代码。现在,如果字节代码不包含Object构造函数的调用,则您的检测代码将无法运行。