2011-12-02 148 views
1

这是我遇到的一件有趣的小事。我用匿名类型瞎搞,我写的是这样的:匿名类型

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

哪些行为到底是你不担心? –

+0

这实际上是一个众所周知的行为。匿名类也获取名称,因为编译器需要以某种方式知道这些类型...... – DejanLekic

+0

**否java中的'undefined behavior' –

回答

3

如果你再看看,你会发现打印出来的类名具有后$1。内部类总是通过连接$和内部类名称来命名包含类的名称。匿名类只需获取一个数字而不是名称。实际上,打印出来的类名是“test.Test中包含的第一个匿名类”。

+0

呃,这是有道理的。 – Tudor

3

正在打印这与new Object() { ... }创建匿名类的名称,如预期的工作。基本上,你已经扩展了Object来创建一个新的类(及其实例),但没有命名它,所以jvm自动将它命名为包含类,后面跟着$和索引

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 

有趣的问题!

3

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

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

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

2

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