2012-02-25 72 views
3

我正在開發一個java應用程序。這是一個抽象類模型和2個派生類模型1和模型2.模型1和模型2的行爲不同,所以我想讓用戶從兩者中選擇一個模型。 它可以等來實現:Java,類類型列表

Model model; 
If(response==1){ 
    model = new Model1(); 
}else if(response==2){ 
    model = new Model2(); 
} 

現在有了這個問題,如果我添加一個新類Model3,我不得不重寫代碼。 我可以創建一個List,在那裏我將從每個類添加一個實例,然後添加一個靜態方法,該方法將返回該類的一個新實例,但是我希望可以用更多樣式來完成。

是否有可能創建一個列表,以容納每個類的類型。從這個列表我可以創建一個菜單來選擇一個模型,然後使用該類型來創建用戶需要的類。

那麼有可能創建一個List<Class>,然後使用Class對象作爲構造函數來創建給定類的實例?

回答

4

您可以創建suppliers列表:

static final List<Supplier<Model>> MODEL_MAKERS = ImmutableList.of(
    new Supplier<Model>() { public Model get() { return new Model1(); } }, 
    new Supplier<Model>() { public Model get() { return new Model2(); } }, 
    new Supplier<Model>() { public Model get() { return new Model3(); } } 
); 

你可以淤泥圍繞與反思,但需要外部Java的正常的異常處理機制加強,需要零參數public構造函數和public類,限制如何代碼可以在維護時通過未被javac檢查的方式進行更改,在此情況下不需要。

+0

+1不使用反射。有時你必須(但如果你在編譯時不知道這個類) – 2012-02-25 20:04:30

+0

@StevenSchlansker,我同意有用於反射。我更喜歡將它限制在Java對象系統和其他系統(文件系統,ORM,嵌入式腳本語言)之間的邊界上。如果您完全使用Java,那麼通常有更好的方式來使用它,而不會影響維護人員重構代碼,遵循程序流程等的能力。 – 2012-02-25 20:43:28

1

如果您確信這將有一個公共的無參數的構造函數,你可以使用Class.newInstance()

對於更復雜的應用,你可以找到一個Constructor對象與Class.getConstructor(s),然後調用它的方式。

一旦你有了這個,把你的Class es變成Map或者做查找和創建實例是相對容易的。

+0

請勿使用'newInstance'。 [javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance%28%29)明確警告:「請注意,此方法傳播任何拋出的異常這個空構造函數,包括一個檢查過的異常,這個方法的使用有效地繞過了編譯時異常檢查,否則編譯器會執行這個異常檢查。 – 2012-02-25 19:12:32

+0

在某些情況下,這正是你想要的。但絕對值得注意。 – 2012-02-25 20:01:26

0

是的,你可以使用類的newInstance()方法來構造一個。但它必須有一個無參數構造函數。

+0

請勿使用'newInstance'。 [javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance%28%29)明確警告:「請注意,此方法傳播任何拋出的異常這個空構造函數,包括一個檢查過的異常,這個方法的使用有效地繞過了編譯時異常檢查,否則編譯器會執行這個異常檢查。 – 2012-02-25 19:12:22

+0

如果你確信構造函數不會拋出異常,那很好。如果你從來沒有打過任何可能拋出異常的東西,你就永遠不會得到任何編碼...... :-) – 2012-02-26 19:11:46

+0

這很好,如果你有信心構造函數不會拋出異常**現在和維護**。 – 2012-02-26 19:14:46