匿名类型
这是我遇到的一件有趣的小事。我用匿名类型瞎搞,我写的是这样的:匿名类型
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标准中指定的还是另一个“未定义的行为”?
如果你再看看,你会发现打印出来的类名具有后$1
。内部类总是通过连接$
和内部类名称来命名包含类的名称。匿名类只需获取一个数字而不是名称。实际上,打印出来的类名是“test.Test中包含的第一个匿名类”。
呃,这是有道理的。 – Tudor
正在打印这与new Object() { ... }
创建匿名类的名称,如预期的工作。基本上,你已经扩展了Object来创建一个新的类(及其实例),但没有命名它,所以jvm自动将它命名为包含类,后面跟着$和索引
是的,这是公认的行为。嵌套类总是表示为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
有趣的问题!
test.Test $ 1不一样test.Test。例如,如果您声明内部类型:
public class Test {
// ...
private class Foo {};
}
那么Foo的限定名称将为test.Test $ Foo。 $ 1表示“test.Test中声明的第一个匿名类型”。
当您使用语法new SomeClass() { ... }
时,您将创建一个匿名类。 Java将匿名类命名为<containing class>$number
,其中number
是包含类中匿名类外观的基于一位的基数。
哪些行为到底是你不担心? –
这实际上是一个众所周知的行为。匿名类也获取名称,因为编译器需要以某种方式知道这些类型...... – DejanLekic
**否java中的'undefined behavior' –