I am studying the workings of Inner Class and inside its bytecode, I was tracing the stack and couldn't understand why is the getClass() called?
I found a similar question for Lambda function but couldn't understand it.
I did try to understand that is required for no null check, after JDK 8 it's been replaced by a static function called requiredNoNull.
Code :
class Outer{
class Inner{
}
public static void main(String args[]){
Outer.Inner obj = new Outer().new Inner();
}
}
ByteCode:
public static void main(java.lang.String[]);
Code:
0: new #2 // class Outer$Inner
3: dup
4: new #3 // class Outer
7: dup
8: invokespecial #4 // Method "<init>":()V
11: dup
12: invokevirtual #5 // Method java/lang/Object.getClass:()Ljava/lang/Class;
15: pop
16: invokespecial #6 // Method Outer$Inner."<init>":(LOuter;)V
19: astore_1
It's a null check in disguise, nothing more, nothing less. Though, in that particular case it's not really needed and future javac
optimize that a little - look at the example below.
May be this will explain the issue better (using java-12, where this getClass
hack has been replaced by Objects::requireNonNull
):
public class Outer {
class Inner {
}
public void left() {
Outer.Inner inner = new Outer().new Inner();
}
public void right(Outer outer) {
Outer.Inner inner = outer.new Inner();
}
}
left
method will compile to something (you can look at the byte code yourself) that will not use Objects::requireNonNull
, since the creation of Outer
happens in place and the compiler can for sure tell that new Outer()
instance is not null
.
On the other hand of you pass Outer
as a parameter, the compiler can't prove that the instance passed is not null for sure, thus Objects::requireNonNull
will be present in the byte code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With