[英]Why does javac allow "new CLS().new InnerCLS()" compile?
Consider the following snippet:考虑以下片段:
(I came across this syntax when inspecting some decompiled class files and this is a minimal representation) (我在检查一些反编译的类文件时遇到了这个语法,这是一个最小的表示)
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 {}
}
This compiles and runs fine (I tested a bunch of JDKs).这编译并运行良好(我测试了一堆 JDK)。
Can someone please explain how come this compiles and what does this code represent?有人可以解释一下这是如何编译的以及这段代码代表什么吗?
This code creates 3 classes:这段代码创建了 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)?
BTW, it can be nested even further like this:顺便说一句,它可以像这样进一步嵌套:
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 {
}
}
}
}
This is how instance (non-static) inner classes work.这就是实例(非静态)内部类的工作方式。 You need an instance of the outer class to instantiate instance of the inner class.
您需要一个外部类的实例来实例化内部类的实例。 This is another example:
这是另一个例子:
var outer = new Outer();
var inner = outer.new Outer.Inner();
See:看:
Inner classes must be instantiated with a this
pointer to the outer class.内部类必须使用指向外部类的
this
指针进行实例化。
The syntax outer.new Inner()
is one way to achieve that (the new instance of Inner
will have the value of outer
as the outer.this reference.语法
outer.new Inner()
是实现这一点的一种方式( Inner
的新实例将把outer
的值作为outer.this 引用。
This is equivalent to having a non-static method in the Main class:这相当于在 Main 类中有一个非静态方法:
class Main {
Inner makeInner() {
/// "this." is implied here, but it is there.
return new Inner();
}
class Inner {
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.