这是我遇到的一个有趣的小事。我正在搞乱匿名类型,我写了类似的东西:
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标准中指定的还是另一种“未定义的行为”?
答案 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
是包含类中匿名类外观的基于一的基数。