匿名类型的类型

时间:2011-12-02 10:59:16

标签: java oop class

这是我遇到的一个有趣的小事。我正在搞乱匿名类型,我写了类似的东西:

public class Test {
    public static void method(Object obj) {
        System.out.println(obj.getClass().getName());
    }

    public static void main(String[] args) {
        method(new Object() {
           int n = 0; 
        });
    }
}

嗯,当打印的结果实际上是test.Test$1时,我感到非常惊讶,这是定义匿名对象的类的名称(如果移动打印类型名称的方法,它仍然是相同的到另一个班)。

有人可以解释这种行为吗?这是在Java标准中指定的还是另一种“未定义的行为”?

5 个答案:

答案 0 :(得分:3)

如果你再看一遍,你会发现打印出的班级名称有一个尾随$1。内部类总是通过将$和内部类名连接到包含类的名称来命名。匿名类只是获取一个数字而不是名称。如此有效,打印出来的类名称是“test.Test中包含的第一个匿名类”。

答案 1 :(得分:3)

它正在打印使用new Object() { ... }创建的匿名类的名称,它按预期工作。基本上,你有扩展的Object来创建一个新类(及其实例)而不命名它,所以jvm自动将它命名为封闭类,后跟$和一个索引

答案 2 :(得分:3)

test.Test $ 1与test.Test不同。例如,如果您声明内部类型:

public class Test {
    // ...
    private class Foo {};
}

然后Foo的限定名称将是test.Test $ Foo。 $ 1表示“test.Test中声明的第一个匿名类型”。

答案 3 :(得分:2)

是的,这是公认的行为。嵌套类始终表示为package.outer类$ nested类。例如test.Test $ NestedTest,对于“test”包中“Test”类中​​的嵌套类“NestedTest”。

匿名类仅按定义顺序编号(因为它们没有名称)。例如,

public static void main(String[] args) {
    method(new Object() {
        int n = 0;
    });

    Object m = new Test() {
        int n = 0;
    };

    method(new Object() {
        int m = 0;
    });

    method(m);
    method(m);
    method(m);
}

将显示

Test$1
Test$3
Test$2
Test$2
Test$2

好问题!

答案 4 :(得分:2)

使用语法new SomeClass() { ... }时,您将创建一个匿名类。 Java将匿名类命名为<containing class>$number,其中number是包含类中匿名类外观的基于一的基数。