2014-11-17 66 views
0

從技術角度來看,下面的方法createColumn()使用泛型會有什麼不利嗎?廣泛使用Java泛型有什麼缺點嗎?

public static <S, T> TableColumn<S, T> createColumn(final Class<S> sType, 
                final Class<T> tType, 
                final int minWidth, 
                final Callback<TableColumn<S, T>, TableCell<S, T>> cellFactory) { 
    TableColumn<S, T> tableColumn = new TableColumn<S, T>(); 

    tableColumn.setMinWidth(minWidth); 
    tableColumn.setCellFactory(cellFactory); 

    return tableColumn; 
} 

以前,我一直在創造TableColumn對象爲JavaFX是這樣的:

TableColumn<Example, String> colExample = new TableColumn<Example, String>(); 
colExample.setMinWidth(100); 
colExample.setCellFactory(myCellFactory); 
... 

TableColumn<Other, String> colAnother = new TableColumn<Other, String>(); 
colAnother.setMinWidth(50); 
colAnother.setCellFactory(myOtherFactory); 
... 

因爲我有很多欄目,我想包創建的工廠方法,並想出了我createColumn()方法的單點創建對象:

TableUtil.createColumn(Example.class, String.class, 100, myCellFactory); 
TableUtil.createColumn(Other.cass, String.class, 50, myOtherFactory); 

創建工作正常這種方式,不過,我覺得有點不安全關於createColumn()中的所有這些泛型(可能因爲我還沒有經常使用泛型)。是否聰明的想法這樣做?或者這種方法有什麼缺點或不安全感?

+1

技術上,因爲類型擦除,則需要進行澆鑄,X,也許X的對象實例化類參數。類型擦除意味着沒有開銷,只是編譯器有時可以爲一個泛型類型的已知實際類型值添加類轉換檢查。即使在不使用泛型時也需要進行手動類型檢查。這對我們所有使用泛型的人來說都是有利的。軟件工程方面的缺點:它僅作爲類參數實現(1),其名稱通常是單個大寫字母(2),當傳遞給其他類時,它變得有點混亂。 Java 8展示了這一點。 –

+0

只是爲了確認,我明白你的意思:如果我想在我的方法中使用''T obj = tType.newInstance();'',我需要''Class''對象,對吧?所以在我的情況下,我很可能會刪除這些參數,但是感謝您的補充。 – user1438038

+1

是的,更好的編碼實踐是調用類的默認構造函數:'tType.getConstructor()'。但也'返回tType。cast(obj);'有時候是需要的。 –

回答

0

解決方案:這就是我在完成所有提示和建議後最終得到的代碼。

public static <S, T> TableColumn<S, T> createColumn(final int minWidth, 
                final Callback<TableColumn<S, T>, TableCell<S, T>> cellFactory) { 
    TableColumn<S, T> tableColumn = new TableColumn<>(); 

    tableColumn.setMinWidth(minWidth); 
    tableColumn.setCellFactory(cellFactory); 

    return tableColumn; 
} 

列創建:

TableColumn<Example, String> colExample = TableUtil.createColumn(100, myCellFactory); 
TableColumn<Other, String> colOther = TableUtil.createColumn(50, myOtherFactory); 
0

這樣做是否聰明?或者這種方法有什麼缺點或不安全感?

您的代碼沒問題。泛型沒有運行時間成本,只在編譯時才存在。

1

泛型只是爲了幫助我們 - 如您所知,這是一個編譯時功能,對我們正在使用的類型應用檢查,並防止意外的ClassCastException s。

由於FAS我所看到的,你不使用你通過Class對象,所以我會重寫你的方法:

public static <S, T> TableColumn<S, T> createColumn(final int minWidth, 
                final Callback<TableColumn<S, T>, 
                TableCell<S, T>> cellFactory) { 
    TableColumn<S, T> tableColumn = new TableColumn<S, T>(); 

    tableColumn.setMinWidth(minWidth); 
    tableColumn.setCellFactory(cellFactory); 

    return tableColumn; 
} 

,並調用它像:

TableUtil.<Example, String>createColumn(100, myCellFactory); 

由於您可以指出泛型類型,因此不需要使用多餘的Class參數來加載方法簽名。

+1

在Java 8中,編譯器將能夠從(正確類型的)單元工廠實例中推斷出類型,因此您應該只能執行'TableUtil.createColumn(100,myCellFactory)'。 –

+0

哇,你說得對!我甚至沒有注意到,我沒有使用「Class」對象。然而,在一些極少數情況下,我將cellFactory設置爲「null」並稍後添加它。如果我遺漏了我的sType和tType屬性並將''cellFactory''設置爲'''''''''''',Java應該如何知道哪些類型用於S和T呢? null''? – user1438038

+1

如果您將它分配給某些您幾乎可以肯定會做的事情,因爲您的方法沒有副作用,編譯器仍然可以從您分配給它的變量的類型推斷出這些類型。例如。如果你做了'TableColumn col = createColumn(100,null);'編譯器推斷'S'是'Person','T'是'String'。 –