为什么Javac允许编译“ new CLS()。new InnerCLS()”?

问题描述 投票:0回答:1

请考虑以下代码段:(在检查一些反编译的类文件时遇到了这种语法,这是一个最小的表示形式)

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 {
            }
        }
    }
}
java javac
1个回答
0
投票
这是实例(非静态)内部类的工作方式。您需要外部类的实例来实例化内部类的实例。这是另一个示例:

var outer = new Outer(); var inner = outer.new Outer.Inner();

参见:


0
投票
内部类必须使用指向外部类的this指针实例化。

语法outer.new Inner()是一种实现方法(Inner的新实例将outer的值作为外部。此引用。

这等效于在Main类中具有非静态方法:

class Main { Inner makeInner() { /// "this." is implied here, but it is there. return new Inner(); } class Inner { } }

© www.soinside.com 2019 - 2024. All rights reserved.