2013-06-25 52 views
1

我想使用枚舉實現基本狀態機;枚舉實現一個接口來管理允許的狀態轉換。但是我想在屬性文件中配置一個實現接口的枚舉類名列表,並且應該在特定的上下文中使用。上下文在運行時確定,並且該上下文鍵映射到屬性文件中的屬性鍵。一旦我從屬性文件中獲取上下文的枚舉類名稱,如何使用該類名稱來獲取實例引用以通過接口方法使用該枚舉?我可以看到您可以使用反射來發現特定枚舉的屬性,但就是這樣。有任何想法嗎?獲取對從枚舉類名實現接口的Java Enum的引用

+0

如果你只有類的名字,則需要使用反射...查看該SO關於使用反射與枚舉http://stackoverflow.com/questions/140537/how-to-use -java-reflection-when-the-enum-type-a-class – fmodos

+0

使用枚舉類名稱會破壞使用枚舉的目的。枚舉權力來自於引用代碼中的實例名稱。如果你想要使用類名,請顯示一個僞代碼行,即使它不能編譯,所以我們知道你的意圖是什麼。 – Bohemian

+0

我正在使用枚舉作爲一個迷你狀態機。 Enum實現了一個接口,該接口有一個方法getNextAllowedStates,它返回一組相同類型的Enum常量。但是我的應用程序具有服務的概念,並且取決於哪個服務請求來自我想要的狀態機實現,因爲每個服務的狀態轉換是不同的。我想只做一些事情 - 請求是服務x獲取枚舉類型y或服務獲取枚舉類型t時。這將從客戶端調用的工廠完成,然後使用接口類型來獲得下一個可能的狀態 – PaulG

回答

1

你說得對使用反射:

  1. 使用Class.forName得到適當的Class對象,一旦你從你的屬性文件讀取的類名。確保您傳入完全合格的課程名稱。你需要在這裏找到各種檢查過的異常。

  2. 確保它是一個實現你的接口,與isEnum方法,並使用從接口的Class對象isAssignableFrom方法的枚舉。

    isEnum()& & YourInterface.class.isAssignableFrom(clazz所)

  3. 使用靜態Enum.valueOf方法從String得到實際的枚舉常量,並將其投放到您的接口。

    (YourInterface) Enum.valueOf(clazz, stringName) 
    
1

我寫了這...它可以幫助你:

public class MyTests { 

    static enum XX implements Runnable { 
    A, B; 
    public void run() { 
     System.out.println("I'm enum value: " + this.name()); 
    } 
    } 

    public static void main(String[] args) throws Exception { 
    new MyTests(); 
    } 

    public MyTests() throws Exception { 
    Class<?> loaded = Class.forName("MyTests$XX"); 
    Class<? extends Runnable> xx = loaded.asSubclass(Runnable.class); 
    Runnable[] enumConstants = xx.getEnumConstants(); 
    for (Runnable runnable : enumConstants) { 
     runnable.run(); 
    } 
    } 

} 

這將打印:

I'm enum value: A 
I'm enum value: B 
+0

採用確保正確類型的'asSubclass()'調用來取代不安全轉換(實際上是非操作)的自由。 – erickson

+0

如果「加載」不是正確的參數化類型,你會不會在任何情況下得到一個異常?此外,你忘了刪除鑄造代碼:) – Renato

+1

哎呀,對不起。是的,您將按照您的方式獲得ClassCastException,但是稍後會在不同位置執行代碼中不存在轉換。在不同的上下文中,這些不安全的強制轉換會在某些遙遠且不相關的代碼中引發神祕的'ClassCastException'錯誤。泛型的唯一要點是提供靜態類型安全保證。但是,如果您忽略警告,則保修無效。 – erickson