当构造函数没有显式调用父类(super class)构造函数(或 this()
)时,编译器会插入 super()
。
如果从类文件中删除此调用(编译后)会发生什么情况?
最佳答案
我自己试过了。
class Test
{
public Test()
{
System.out.println("Hello World");
}
public static void main(String[] args)
{
new Test()
}
}
我编译并删除了invokespecial java/lang/Object/<init>()V
使用类文件编辑器从构造函数中获取。
JVM 似乎拒绝加载该类:
Exception in thread "main" java.lang.VerifyError: Operand stack overflow
Exception Details:
Location:
Test.<init>()V @4: ldc
Reason:
Exceeded max stack size.
Current Frame:
bci: @4
flags: { flagThisUninit }
locals: { uninitializedThis }
stack: { uninitializedThis, 'java/io/PrintStream' }
Bytecode:
0000000: 2ab2 0002 1203 b600 04b1
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
我仍然不知道这是否是已定义的行为。
编辑
根据 Raedwald 的说法,我还必须更改堆栈操作。
所以我也删除了aload_0
这是在 super 构造函数调用之前。
现在我得到以下异常:
Exception in thread "main" java.lang.VerifyError: Constructor must call super()
or this() before return
Exception Details:
Location:
org/exolin/geno/Test.<init>()V @8: return
Reason:
Error exists in the bytecode
Bytecode:
0000000: b200 0212 03b6 0004 b1
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
这让我很好奇,所以我将构造函数指令重新排序为:
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Message"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
aload_0
invokespecial java/lang/Object/<init>()V
return
哪个有效!
关于java - 如果我从类文件中删除 super 构造函数调用会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24349944/