Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if I remove the super constructor call from class file?

When a constructor doesn't have a explicit call of the super class constructor (or this()) then the compiler inserts super().

What would happen if this call was removed from the class file (after compilation)?

like image 322
Jimmy T. Avatar asked Jun 22 '14 09:06

Jimmy T.


People also ask

What happens when you don't use super () constructor?

Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error.

Is it mandatory to call super constructor in Java?

However, using super() is not compulsory. Even if super() is not used in the subclass constructor, the compiler implicitly calls the default constructor of the superclass.

Is Super necessary in constructor?

If the SuperClass has a default Constructor there is no need to call it using"super()" explicitly, it will be invoked implicitly.

What is the purpose of using super constructor?

The super keyword is used to call the constructor of its parent class to access the parent's properties and methods. Tip: To understand the "inheritance" concept (parent and child classes) better, read our JavaScript Classes Tutorial.


1 Answers

I tried it myself.

class Test
{
    public Test()
    {
        System.out.println("Hello World");
    }

    public static void main(String[] args)
    {
        new Test()
    }
}

I compiled it and removed invokespecial java/lang/Object/<init>()V from the constructor with a class file editor.

It seems like the JVM refuses to load the class:

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)

I still don't know if that is a defined behaviour.

EDIT

According to Raedwald I also have to alter the stack manipulation.

So I also removed aload_0 which was before the super constructor call.

Now I get the following exception:

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)

This made me curious so I reordered the constructor instructions to:

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

Which worked!

like image 183
Jimmy T. Avatar answered Sep 29 '22 00:09

Jimmy T.