2011-12-02 251 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是包含類中匿名類外觀的基於一位的基數。