我正在研究内部类及其字节码内部的工作原理,我正在跟踪堆栈,但不明白为什么要调用 getClass()?
我找到了一个 similar question for Lambda function但无法理解。
我确实试图理解没有空检查是必需的,在 JDK 8 之后它被一个名为 requiredNoNull 的静态函数所取代。
代码:
class Outer{
class Inner{
}
public static void main(String args[]){
Outer.Inner obj = new Outer().new Inner();
}
}
字节码:
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 ,仅此而已。不过,在那种特殊情况下,它并不是真正需要的, future 的 javac
会对其进行一些优化 - 请看下面的示例。
可能这会更好地解释问题(使用 java-12,其中 getClass
hack 已被 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
方法将编译为不使用Objects::requireNonNull
的内容(您可以自己查看字节码),因为Outer
的创建发生在适当的位置,编译器可以确定 new Outer()
实例不是 null
。
另一方面,当您将 Outer
作为参数传递时,编译器无法证明传递的实例肯定不是 null,因此 Objects::requireNonNull
将出现在字节码中。
关于java - 为什么我们为内部类创建对象时会调用getClass()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56881751/