Reputation: 587
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>
):
java.lang.Object.<init>
? Upvotes: 5
Views: 805
Reputation: 1505
Here is the bytecode of method of a "Foo" class
public <init>()V
L0
LINENUMBER 1 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this LFooTest; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
when you try to create a new instance of Foo, will INVOKESPECIAL java/lang/Object. ()V, and after that, the object will be created in heap memory and the reference in stack will be return and assigned to "this". so, in my opinion, the answer of your question should be "after calling java.lang.Object.init()”
Upvotes: 0
Reputation: 39461
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.
Upvotes: 5