2015-10-05 76 views
0

您好我目前正在研究一些遺留的代碼,我已經繼承,我需要將一種類型轉換爲另一種類型來結束我的重構。 我遇到的問題是,我有一個返回Class<AbstractSuperClass>一個對象,但我需要將其轉換成AbstractSuperClass //(concrete object although abstract)如何將通用類型轉換爲Java中的具體類型

我試圖做的是使用枚舉常量來表示一個抽象類的具體子類,然後使用實例化對象的常量。但我所有的鑄造嘗試迄今都失敗了。

如果有人能夠在這種情況下爲正確的方向提供一些指針,那將是最有幫助的。

+5

'Class'對象不是'AbstractSuperClass'對象。鑄造將永遠不會工作。請說明你在做什麼或試圖做什麼。 –

+0

嗨,謝謝你的回答,我試圖做的是通過enum(ENUMVAL(baseClassFoo).class)返回Class ,如果我能成功地將此返回類型轉換爲我在其他類中的抽象類方法我可以消除大量冗餘代碼,並使用baseClassFoo中定義的算法,而不必使用動態調度來檢查條件。 – JKT

+0

你問如何實例化一個類,因爲它的'Class'對象? (通過反射?) –

回答

3

你的問題並不完全清楚。它看起來像你試圖使用枚舉常量來表示一個抽象類的具體子類,並且你希望能夠使用這些常量來實例化對象。這是可能的:

public enum ConcreteClass { 

    CONCRETE1(Concrete1.class), 
    CONCRETE2(Concrete2.class); 

    private final Class<? extends AbstractClass> clazz; 

    private ConcreteClass(Class<? extends AbstractClass> clazz) { 
     this.clazz = clazz; 
    } 

    public AbstractClass instantiate() throws InstantiationException, IllegalAccessException { 
     return clazz.newInstance(); 
    } 
} 

用這個你可以做AbstractClass obj = ConcreteClass.CONCRETE2.instantiate();。您必須在try塊中執行此操作,因爲這些例外是已檢查的例外情況。

就我個人而言,我不喜歡使用反射。我想用Supplier<AbstractClass>是更好的(需要Java 8):

public enum ConcreteClass { 

    CONCRETE1(Concrete1::new), 
    CONCRETE2(Concrete2::new); 

    private final Supplier<AbstractClass> supplier; 

    private ConcreteClass(Supplier<AbstractClass> supplier) { 
     this.supplier = supplier; 
    } 

    public AbstractClass instantiate(){ 
     return supplier.get(); 
    } 
} 

這種方法不使用反射,不涉及檢查異常,而且是更普遍的,因爲它可以與只具有靜態類使用工廠方法和沒有公共構造函數。

+0

沒有通配符在第二個解決方案? :)但我同意,通配符是地獄。 – ZhongYu

+0

@ bayou.io我不認爲通配符會在第二種解決方案中爲您購買任何東西,而在第一個示例中,您需要它們進行編譯。我是那些真正喜歡通配符的陌生人之一。 –

+1

嗯...是的,所有的枚舉構造函數的調用網站都是已知的,因此沒有通配符就沒有問題了。我會[爭論](http://bayou.io/draft/Wildcard_Case_Studies.html#Missing_Wildcards)通常可以省略通配符的真正原因是參數通常是lambda表達式或方法引用,java類型推斷可以採用照顧適合的類型。 – ZhongYu

相關問題