2014-09-02 104 views
0

我有一個泛型類型CHILDITEMS的ObservableList,其中<CHILDITEMS extends PlanItem>。我如何知道在運行時ObservableList是什麼類型?ObservableArrayList:如何通過反射獲取通用類型?

/*Get a reference to the child items of the currently viewed item.*/ 
    ObservableList<CHILDITEMS> childItems = (ObservableList<CHILDITEMS>) viewing.getChildItems(); 
    /*Set the child items label to the type of the child items.*/ 
    childItemsLabel.setText("Name of CHILDITEMS class"); 

我不能使用getFields,因爲CHILDITEMS不是一個真正的字段。在ObservableList.class上使用getType只返回泛型類型「E」,而不是運行時的內容。

CHILDITEM類型可能是目標,目標,策略或任務。我想知道它在運行時是什麼。

+1

泛型是一個編譯時構造。那就是編譯器會用它們來檢查你是否沒有意外地使用Object。在運行時,您的'ObservableList '變成'ObservableList '。在引擎蓋下,它將像使用Java的預泛型版本一樣使用強制轉換。這意味着如果不進行大量'instanceof'測試,就無法做到自己想做的事。 – Romski 2014-09-02 00:41:17

回答

0

正如@Romski在評論中所說,這些信息甚至在運行時都沒有保留。

如果你知道你的列表是非空的,你只把確切類型的項目在列表中(即你的ObservableList<P>只包含運行時類型P的項目,而不是是P子類的實例任何物品),那麼你當然可以做list.get(0).getClass(),但這是不太可能的情況,並不是非常健壯。

您也可以考慮爲列表創建一個包裝,使用類型標記來保留該類型。喜歡的東西:

public class TypedObservableList<P extends PlanItem> { 
    private final Class<P> type ; 
    private final ObservableList<P> list ; 

    public TypedObservableList(Class<P> type) { 
     this.type = type ; 
     this.list = FXCollections.observableArrayList(); 
    } 

    public Class<P> getType() { 
     return type ; 
    } 

    public ObservableList<P> getList() { 
     return list ; 
    } 
} 

現在你結束了大量的代碼看起來像

TableView<Goal> goalTable = new TableView<>(); 
TypedObservableList<Goal> goals = new TypedObservableList<>(Goal.class); 
goalTable.setItems(goals.getList()); 

,但至少你現在可以做

TypedObservableList<? extends PlanItem> typedList = viewing.getChildItems(); 
childItemsLabel.setText(typedList.getType().getSimpleName()); 

你還沒說什麼viewing是,但你也許可以想出類似的解決方案,在那個類中持有類型令牌,所以你最終會得到

childItemsLabel.setText(viewing.getChildType().getSimpleName()); 
+0

這是一個有點破解的解決方案,但是由於Java的當前侷限性,這是我能做的唯一的事情。 – 2014-09-03 07:13:00