2011-01-28 159 views
18

的成員我試圖在Java中實現一個排序列表作爲一個簡單的練習。爲了使其通用,我有一個add(Comparable obj),所以我可以將它與任何實現Comparable接口的類一起使用。Java「unchecked調用compareTo(T)作爲原始類型java.lang.Comparable」

但是,當我使用obj.compareTo(...)在代碼的任何地方,我得到"unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable"從編譯器(帶-Xlint:unchecked選項)。代碼工作得很好,但我無法弄清楚如何擺脫那個惱人的消息。

任何提示?

回答

22

在本質上,這種警告說,Comparable對象不能相比的任意對象。 Comparable<T>是一個通用接口,其中類型參數T指定了該對象可以比較的對象的類型。

因此,爲了正確使用Comparable<T>,你需要讓你的排序列表通用,以表達一個約束,你的列表存儲可以相互比較的對象,這樣的事情:

public class SortedList<T extends Comparable<? super T>> { 
    public void add(T obj) { ... } 
    ... 
} 
+4

應該是`T延伸可比`。 – ColinD 2011-01-28 16:24:36

1

你需要「檢查」或定義的可比對象,像這樣:

add(Comparable<Object> obj) 
9

使用類似Comparable這樣的接口作爲方法參數不會使您的類變爲泛型,而是聲明和使用泛型類型參數是您如何使其泛型。

快速正骯髒的答案:由於你正在使用Comparable,這是一個通用的接口,作爲一個原始類型,而不是給它一個特定類型的參數,如Comparable<String>收到警告。

爲了解決這個問題,使add()一般通過指定類型參數:

<T extends Comparable<? super T>> add(T obj) { ... } 

但這種速戰速決不會解決你的類是不安全的一般問題。畢竟,不應該列表中的所有對象都是同一類型的?這個add方法可以讓你將不同的類型放入同一個列表中。當您嘗試比較不同類型的數據時(如何將compareToObject實例與Number實例或String實例進行比較)會發生什麼?你可以依賴類的用戶來做正確的事情,並確保他們只在你的列表中保留一種東西,但是一個通用的類會讓編譯器執行這個規則。

更好的方法:正確的解決方法是,你的排序列表類應該可能是通用的整體,就像在java.util其他集合類。

你可能會喜歡這樣的:

public class SortedList<T extends Comparable<? super T>> 
implements Iterable<T> { 
    ... 
    public void add(T item) { ... } 
    public Iterator<T> iterator() { ... } 
    ... 
} 

注意,當類是通用的,在add方法使用的類的形式類型參數,而不是宣稱自己的形式類型參數。

應該有很多教程關於如何創建一個泛型類在網絡上,但這裏有一個簡單的例子:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#FAQ002

class Pair<X,Y> { 
    private X first; 
    private Y second; 
    public Pair(X a1, Y a2) { 
    first = a1; 
    second = a2; 
    } 
    public X getFirst() { return first; } 
    public Y getSecond() { return second; } 
    public void setFirst(X arg) { first = arg; } 
    public void setSecond(Y arg) { second = arg; } 
}