为什么 javac 允许 "new CLS().new InnerCLS()" 编译?
Why does javac allow "new CLS().new InnerCLS()" compile?
考虑以下片段:
(我在检查一些反编译的 class 文件时遇到了这种语法,这是一个最小的表示)
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 classes:
1. Main - This creates the following code (I removed the irrelevant parts):
new Main
dup
new Main
dup
invokespecial Method Main <init> ()V
dup
invokevirtual Method java/lang/Object getClass ()Ljava/lang/Class;
pop
invokespecial Method Main <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 - This creates the following class (I removed the irrelevant parts):
final class Main 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 {
}
}
}
}
这就是实例(非静态)内部 class 的工作方式。您需要外部 class 的实例来实例化内部 class 的实例。这是另一个例子:
var outer = new Outer();
var inner = outer.new Outer.Inner();
参见:
内部 classes 必须用指向外部 class 的 this
指针实例化。
语法 outer.new Inner()
是实现该目标的一种方法(Inner
的新实例将具有 outer
的值作为 outer.this 引用。
这相当于在 Main 中有一个非静态方法 class:
class Main {
Inner makeInner() {
/// "this." is implied here, but it is there.
return new Inner();
}
class Inner {
}
}
考虑以下片段:
(我在检查一些反编译的 class 文件时遇到了这种语法,这是一个最小的表示)
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 classes:
1. Main - This creates the following code (I removed the irrelevant parts):
new Main
dup
new Main
dup
invokespecial Method Main <init> ()V
dup
invokevirtual Method java/lang/Object getClass ()Ljava/lang/Class;
pop
invokespecial Method Main <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 - This creates the following class (I removed the irrelevant parts):
final class Main 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 {
}
}
}
}
这就是实例(非静态)内部 class 的工作方式。您需要外部 class 的实例来实例化内部 class 的实例。这是另一个例子:
var outer = new Outer();
var inner = outer.new Outer.Inner();
参见:
内部 classes 必须用指向外部 class 的 this
指针实例化。
语法 outer.new Inner()
是实现该目标的一种方法(Inner
的新实例将具有 outer
的值作为 outer.this 引用。
这相当于在 Main 中有一个非静态方法 class:
class Main {
Inner makeInner() {
/// "this." is implied here, but it is there.
return new Inner();
}
class Inner {
}
}