使用JVM字节码的编译器,我注意到一些没有多大意义的构造函数:
每个Java类的每个构造函数都调用super
构造函数,甚至是Object
的直接子类。这是由Java编译器强制执行的(当它无法在构造函数的开头隐式添加调用时)和Bytecode Verifier强制执行,如使用自定义.class
文件的此错误所示:
java.lang.VerifyError: Constructor must call super() or this() before return
Exception Details:
Location:
dyvil/test/Main.<init>()V @0: return
Reason:
Error exists in the bytecode
Bytecode:
0000000: b1
对于某些带有字段等的随机类的子类,这是有意义的,因为这些字段必须初始化,但是在Object
的子类的情况下,这是非常< / em>对nop方法的公共调用(+方法调用开销)。这引出了一些问题:
Object
的情况下,该类应该已经在任何给定点加载,那么为什么需要调用它的构造函数呢?编辑:Object
构造函数的字节码
public void <init>()
L0
LINENUMBER 37 L0
RETURN
MAXSTACK = 0
MAXLOCALS = 1
正如您可能看到的,此构造函数根本不执行任何操作。
答案 0 :(得分:2)
首先,RETURN
中的单个Object.<init>
并不意味着Object
的构造函数是NOP。
Object
类通常是JVM内部函数,JVM比它的字节码更了解它。例如,HotSpot使用Object.<init>
to register finalizers。
关于Object.<init>
的最好的事情是 - 它是任何实例分配不可避免地要求的唯一方法。看看它是一个强大的功能:你可以在Object.<init>
上设置一个断点,一次拦截所有构造函数。您还可以使用Instrumentation API修改Object
的构造函数以跟踪所有分配,依此类推......
关于性能 - 是的,JIT编译器在不需要时消除了不必要的方法调用,例如:当这个方法没有断点时,没有finalize
等。对于其他琐碎的方法也是如此,不仅仅是Object.<init>
。所以它们没有性能影响。
答案 1 :(得分:1)
Object
是一个类似于其他类的类。它有一个必须被调用的构造函数。 JVM规范并不排除Object
在其实例初始化方法中有指令。java.lang
的所有类(如果我没记错的话,我已经读了很长时间了)。另见1. Object
的构造函数。如果您认为:测量!