2011-02-09 105 views
11

如果我有一個類com.example.test.Enum2.Test如下面的代碼,爲什麼getCanonicalName()返回com.example.test.Enum2.TestClass.forName()要求"com.example.test.Enum2$Test"作爲參數?

有沒有一種方法是一致的,這樣我可以序列化/反序列化其名稱的枚舉值,而無需檢查每個$ VS .可能性,當枚舉是嵌套類?

package com.example.test; 

import java.util.Arrays; 

public class Enum2 { 

    enum Test { 
     FOO, BAR, BAZ; 
    } 

    public static void main(String[] args) { 
     for (String className : Arrays.asList(
       "com.example.test.Enum2.Test", 
       "com.example.test.Enum2$Test")) 
     { 
      try { 
       Class<?> cl = Class.forName(className); 
       System.out.println(className+" found: "+cl.getCanonicalName()); 
      } 
      catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
      } 
     } 

     System.out.println(Test.FOO.getDeclaringClass().getCanonicalName()); 
    } 
} 

澄清:我正在尋找一個好辦法來處理在實際應用中(不只是上述做作測試用例)這個問題,或者:

一個。使用getCanonicalName()的輸出(僅虛線的名稱)序列化/反序列化,並且對於Class.forName()依次例如嘗試每種可能性。第一個"com.example.test.Enum2.Test",然後"com.example.test.Enum2$Test",然後"com.example.test$Enum2$Test"

b。使用適當的$符號,以便Class.forName()第一次正常工作。但是這需要我實現getCanonicalName()的替代方法,該方法會生成一個與Class.forName()一致的字符串。

我傾向於方法(b),部分來自直覺,部分原因是方法(a)在包名大寫的情況下有歧義:com.example.Test.Enum2和com.example.Test $如果存在com/example/Test/Enum2.java和包含Enum2內部類的com/example/Test.java,則Enum2都可以是有效的輸入,即Class.forName()

...但我不知道如何實現它。有任何想法嗎?

回答

9

ARGH:我應該只是簡單地使用Class.getName()而不是Class.getCanonicalName()

5

那麼,對於getCanonicalName狀態的文檔:

返回由Java語言規範定義基礎類的規範名稱。

(重點煤礦。)

在Java語言,嵌套表示以點。就圖書館和虛擬機而言,嵌套類只是名稱中帶有$的類。

你還沒有說過你在談論什麼樣的序列化 - 只要你對這兩個方向一致,它應該沒問題。

+0

無賴。所以語言的名字!= VM​​的名字。 :-(是否有一種更簡單的方法將虛線符號轉換爲正確的$,而不必依次嘗試每種可能性(例如com.example.test.Enum2.Test,com.example.test.Enum2 $ Test,com .example.test $ Enum2 $ Test等等) – 2011-02-09 18:49:17