java - 如果我从类文件中删除 super 构造函数调用会怎样?

标签 java constructor .class-file

当构造函数没有显式调用父类(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/

相关文章:

java - 获取 JSON 数组 Android 的元素

java - 在 Samsung Galaxy S6 android 7 上立即取消通知

tomcat - 修改.class文件需要重启Tomcat吗

Java HashMap containsKey 始终为 false

JavaX MIDI - 使用自定义音色播放 MIDI 文件

java - 从http请求参数构造实例的最佳方法

c# - 静态构造函数中的异常

java - 将基类对象转换为扩展基类的类时出现 ClassCastException

java - 如何在运行时加载 .class 文件以与 JUnitCore.runclasses() 一起使用

java - 如果我更改 eclipse 中的 bin 文件夹,为什么 jar 会损坏?