2011-01-28 9 views
18

Sto provando a implementare un elenco ordinato come un semplice esercizio in Java. Per renderlo generico ho un add(Comparable obj) quindi posso usarlo con qualsiasi classe che implementa l'interfaccia Comparable.Java "chiamata non verificata per confrontareTo (T) come membro del tipo non elaborato java.lang.Comparable"

Tuttavia, quando uso il codice obj.compareTo(...) in qualsiasi punto del codice ottengo "unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable" dal compilatore (con l'opzione -Xlint:unchecked). Il codice funziona bene ma non riesco a capire come sbarazzarmi di quel fastidioso messaggio.

Eventuali suggerimenti?

risposta

22

In sostanza, questo avviso dice che Comparable oggetto non può essere paragonato a oggetti arbitrari. Comparable<T> è un'interfaccia generica, in cui il parametro di tipo T specifica il tipo di oggetto a cui questo oggetto può essere confrontato.

Così, al fine di utilizzare Comparable<T> correttamente, è necessario per rendere il vostro elenco ordinato generici, per esprimere un vincolo che l'elenco memorizza gli oggetti che possono essere comparati a vicenda, qualcosa di simile:

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

Dovrebbe essere 'T estende Paragonabile '. – ColinD

+0

Beh, l'ho provato come era prima e ha funzionato. – 3mpty

1

hai bisogno di "controllare" o definire l'oggetto paragonabile in questo modo:

add(Comparable<Object> obj) 
9

L'utilizzo di un'interfaccia come Comparable come parametro del metodo non rende generica la classe, dichiarando e utilizzando parametri di tipo generico è come la si rende generica. risposta

Quick-n-sporco: Stai ricevendo l'avviso perché si sta utilizzando Comparable, che è un'interfaccia generica, come un tipo grezzo, piuttosto che dando uno specifico argomenti di tipo, come Comparable<String>.

Per risolvere questo problema, fanno add() generico specificando parametri di tipo:

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

Ma questa soluzione rapida non risolve il problema generale che la classe è a rischio. Dopotutto, non tutti gli oggetti del tuo elenco dovrebbero essere dello stesso tipo? Questo metodo add consente di inserire tipi diversi nello stesso elenco. Che cosa accade quando si tenta di confrontare tipi eterogenei (come si fa a compareTo un'istanza Object a un'istanza Number oa un'istanza di String)? Puoi fare affidamento sull'utente della classe per fare la cosa giusta e assicurarti che rimangano solo 1 tipo di cosa nella tua lista, ma una classe generica permetterà al compilatore di applicare questa regola.

L'approccio migliore: La corretta correzione è che la classe lista ordinata dovrebbe essere probabilmente essere generico globale, proprio come le altre classi di raccolta in java.util.

si sarebbe probabilmente come qualcosa di simile:

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

Si noti che quando la classe è generico, il metodo add utilizza il parametro di tipo formale classi piuttosto che dichiarare il proprio parametro di tipo formale.

Ci dovrebbe essere un sacco di tutorial sul web su come creare una classe generica, ma ecco un esempio veloce:

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; } 
} 
Problemi correlati