簡體   English   中英

我在Java中的泛型測試不起作用!

[英]My generics test in Java doesn't work!

我正在做一些Java學習,特別是在泛型領域。

我對C#中的泛型非常熟悉,但在Java中,這是一個完全不同的故事。

我使用了一些適合測試的樣本,我能夠用Java復制我的大部分C#代碼。

但是,當我嘗試以下示例時,它不起作用:

private static <T> void swapKundeData(ArrayList<T> data, int index1, int index2) {

    T temporary = (T) data.get(index1);

    data.set(index1, data.get(index2)); //Does not compile
    data.set(index2, temporary); //Does not compile

}

我收到的錯誤是:

在ArrayList類型中的方法set(int,capture#5-of?extends ExtendTest)不適用於參數(int,ExtendTest)

相當於這個在C#中運行得很好 - 所以發生了什么?

我已經讀到Java在泛型方面受到了很多批評。 這是批評的一部分嗎? 數據變量的Remove和Add方法工作得很好。

好吧,我會用

List<Kunde> 

代替

ArrayList<?>

因為你無論如何都要去昆德:)。

它不起作用的原因是您不知道傳遞的對象的類型。 因此,如果您設置一個可能是錯誤類型的Kunde(因為使用ArrayList <?>,您可以傳遞ArrayList <String>並在其上設置Kunde將是錯誤的類型)。

另一種可能性是:

private static <T> void swapData(List<T> data, int index1, int index2) {

    T temporary = data.get(index1);

    data.set(index1, data.get(index2)); //Does compile
    data.set(index2, temporary); //Does compile

}

要完成我的咆哮,只需使用Collections的swap方法。

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#swap(java.util.List,int,int

如果你知道你的ArrayList包含Kunde對象,那么你應該聲明方法參數ArrayList<Kunde> ; 沒有必要使用通配符。 正如您所看到的,它會導致編譯時類型錯誤。

有關該問題的完整說明,請參閱http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html

你的問題的原因是你聲明了一種ArrayList<?> ,這意味着“一個列表應該只包含某種類型,但我不知道哪一種”。 這樣做的結果是,你從列表中取出的對象唯一知道的是它們是Object類型,因為一切都是(除了原語,它不能在集合中)。 但更重要的是,您不能將任何內容放入列表中,因為您不知道它受約束的類型。

這就是為什么使用? 通配符很少適合。 在幾乎所有情況下,您應該使用具體類型或命名有界類型:

private static void swapKundeData(List<Kunde> data, int index1, int index2) {
    Kunde temporary = data.get(index1);
    data.set(index1, data.get(index2));
    data.set(index2, temporary);
}

請注意List接口的使用,這使得代碼可以更靈活地接受它所接受的內容。

private static <T> void swap(List<T> data, int index1, int index2) {
    T temporary = data.get(index1);
    data.set(index1, data.get(index2));
    data.set(index2, temporary);
}

這是真正通用的解決方案,它是類型安全的,但不需要知道列表元素的類型。 你實際上並沒有通過使用Generics獲得任何類型的安全性( Object也可以這樣做),但你可以返回一個交換元素,編譯器會知道返回值與列表元素的類型相同。

問題是Eclipse。

我沒有保存文件,所以顯然沒有重新編譯。

哇,我對IDE的無能力和煩惱感到非常滿意,比如速度。

那好吧。

我注意到這個問題已被編輯,以前的答案沒有多大意義。

從查看問題編輯,值得注意的是,如果您希望客戶端看到如下方法:

public static void swapKundeData(List<?> data, int index1, int index2) {

但是你想要實現:

public static <T> void swapKundeData(List<T> data, int index1, int index2) {

可以捕獲通配符,並且具有客戶端友好表單的方法可以轉發為實現友好的形式:

public static void swapKundeData(List<?> data, int index1, int index2) {
    swapKundeDataImpl(data, index1, index2)
}

private static <T> void swapKundeDataImpl(List<T> data, int index1, int index2) {

(我在這里假設“kunde”不是一個粗魯的詞。)

總結Oli所說的內容,你不能分配給“未知類型”的集合嗎? 因為java不知道應該去那里。 但是,由於每個“未知類型”仍然是一個對象,因此它們可以安全地調用“getter”方法,因為它們將始終返回Object類型的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM