2014-01-10 113 views
1

我有多個類都從相同的Block類繼承,並希望基於變量值實例化其中的一個類。從列表中選擇一種類型

這裏是我做了現在:

public enum MapCases { 
    FLOOR (Floor.class), // These are all subclass of my Block class 
    WALL (Wall.class), 
    ROCK (Rock.class); 

    private Class<?> blockType; 

    MapCases (Class<?> pointing) { 
     this.block = pointing; 
    } 

    public Class<?> getType() { 
     return this.blockType; 
    } 
}; 

後來的後來,我嘗試實例給他們一些數據:

private Block[] blocks; // Array of the mother type 
    ... 
    blocks = new Block[data.length]; // data is an int array 
    for (int i = 0; i < data.length; i++) { 
     int choice = data[i]; 
     Class<?> blockType = MapCases.values()[choice].getType(); 
     blocks[i] = new blockType(); // blockType is of unresolved type 
    } 

但是Eclipse顯示我的錯誤說,它不能解析blockType到一個類型(這看起來是合乎邏輯的,因爲java還不知道類型)。

我怎麼能達到我想要做的?

+1

試試'?擴展Block'到處都有'?'。 –

+0

我不知道這些事情是可能的。它雖然不起作用,但類型仍未解決。 – Malharhak

回答

3

你不應該需要反射來做到這一點。考慮這個:

public enum MapCases { 
    FLOOR { 
     @Override 
     public Block makeBlock() { 
      return new Floor(); 
     } 
    }, 
    WALL { 
     @Override 
     public Block makeBlock() { 
      return new Wall(); 
     } 
    }, 
    ROCK { 
     @Override 
     public Block makeBlock() { 
      return new Rock(); 
     } 
    }; 

    public abstract Block makeBlock(); 
} 

在這種情況下,枚舉本身作爲工廠,而不是Class令牌原持有。


請注意,如果你是要堅持與Class令牌,應該輸入爲Class<? extends Block>,如評論Elliott Frisch points out。然後致電blockType.getConstructor().newInstance(),其中GGrec's answer demonstrates將返回Block的實例。

+0

有趣。這似乎是最好的方式。我現在試試 – Malharhak

+0

正在用同樣的東西寫另一個答案。非常好,乾淨! – GGrec

+0

它似乎完美地工作。謝謝! – Malharhak

2

使用反射從類藍圖創建一個新實例。

模式:

Class.forName(className).getConstructor().newInstance(); 

您的情況:

blocks[i] = blockType.getConstructor().newInstance(); 
+0

看起來更好,但Eclipse仍然看到一個錯誤,並告訴我要包裝一個處理各種實例化異常的try catch。我認爲它不知何故需要一個精確的類型,不像我所做的。 – Malharhak

+0

所有反射機制都需要檢查異常處理。所以趕上他們是可以的。 – GGrec

相關問題