java - 为什么 javac 允许“new CLS().new InnerCLS()”编译?
问题描述
考虑以下片段:(
我在检查一些反编译的类文件时遇到了这种语法,这是一个最小的表示)
public class Main {
public static void main(String[] args) {
Main.Inner o = new Main().new Inner() {};
System.out.println("Bye from " + o.getClass());
}
class Inner {}
}
这编译并运行良好(我测试了一堆 JDK)。
有人可以解释一下这是怎么编译的,这段代码代表什么?
此代码创建 3 个类:
1. Main - This creates the following code (I removed the irrelevant parts):
new Main$1
dup
new Main
dup
invokespecial Method Main <init> ()V
dup
invokevirtual Method java/lang/Object getClass ()Ljava/lang/Class;
pop
invokespecial Method Main$1 <init> (LMain;)V
Why is it calling getClass (the result is popped anyway)?
2. Main$Inner - This class looks like as would expect an inner class to look
3. Main$1 - This creates the following class (I removed the irrelevant parts):
final class Main$1 extends Main$Inner
method <init> : (LMain;)V
aload_0
aload_1
dup
invokevirtual Method java/lang/Object getClass ()Ljava/lang/Class;
pop
invokespecial Method Main$Inner <init> (LMain;)V
return
Again, why is it calling getClass (the result is popped anyway)?
顺便说一句,它可以像这样进一步嵌套:
public class Main {
public static void main(String[] args) {
Object o = new Main().new Inner1().new Inner2().new Inner3() {};
System.out.println("Bye from " + o.getClass());
}
class Inner1 {
class Inner2 {
class Inner3 {
}
}
}
}
解决方案
这就是实例(非静态)内部类的工作方式。您需要一个外部类的实例来实例化内部类的实例。这是另一个例子:
var outer = new Outer();
var inner = outer.new Outer.Inner();
看:
推荐阅读
- c++ - 如何在 C++ 中的赋值中命名类标识符?
- r - 如何在ggplot2的融化数据框中创建两个变量的图?
- python - 在熊猫数据框中修剪字符串(日期,时间)
- html - HTML 页面嵌入 Google Docs Viewer / Office Web Apps Viewer for Intranet 文件
- r - 遍历列以对每行的前 2 个数字求和
- swift - 如何在文本视图中停止计时器?
- android - 如何在共享首选项上保存 RecyclerView 的 spanCount?
- javascript - 在javascript中追加将div转换为文本
- android - Glide在RecyclerView的条件句中乱码
- flutter - 颤振:[错误:颤振/lib/ui/ui_dart_state.cc(166)]未处理的异常