Search code examples
javajvmbytecodebytecode-manipulation

When is a Java object fully initialized?


As one may know, an object just allocated by the new bytecode is not initialized, and is thus not a java.lang.Object. If I do runtime bytecode manipulation and give that object to a method, the JVM will complain or even crash (because the "thing" I gave it is not a java.lang.Object).

So, my question is, when are objects "fully" initialized, i.e. become a java.lang.Object? Is that when the constructor (<init>):

  • is called?
  • returns?
  • some time before it returns?
  • calls java.lang.Object.<init>?
  • some other timing?

Solution

  • From the perspective of any given <init> method, the this value is considered initialized after the call to invokespecial returns, whether that is calling another <init> method in the same class or a superclass.

    Likewise, for objects created with the new instruction, they are considered initialized once you invokespecial an <init> method on them.

    Note that initialization tracking is local to a method. Bytecode verification is done on a method by method basis and each method only sees the objects that are created within it and the calls to methods. The fact that it is impossible to initialize the this value in a constructor without calling another constructor ensures that it will eventually chain up to a java.lang.Object constructor unless it throws or goes into an infinite loop.