2011-01-28 14 views
18

Estoy tratando de implementar una lista ordenada como un ejercicio simple en Java. Para hacerlo genérico, tengo un add(Comparable obj), así que puedo usarlo con cualquier clase que implemente la interfaz Comparable.Java "llamada sin marcar para comparar a (T) como miembro del tipo sin formato java.lang.Comparable"

Pero, cuando uso obj.compareTo(...) en cualquier parte del código obtengo "unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable" del compilador (con la opción -Xlint:unchecked). El código funciona bien pero no puedo descifrar cómo deshacerme de ese mensaje molesto.

¿Alguna pista?

Respuesta

22

En esencia, esta advertencia dice que Comparable objeto no se puede comparar con objetos arbitrarios. Comparable<T> es una interfaz genérica, donde el parámetro de tipo T especifica el tipo de objeto con el que se puede comparar este objeto.

Por lo tanto, con el fin de utilizar Comparable<T> correctamente, necesita para hacer su lista ordenada genérico, para expresar una restricción que su lista almacena objetos que pueden ser comparadas entre sí, algo como esto:

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

debería ser 'T se extiende comparable '. – ColinD

+0

Bueno, lo probé como era antes y funcionó. – 3mpty

1

es necesario "marcar" o definir el objeto comparable, así:

add(Comparable<Object> obj) 
9

El uso de una interfaz como Comparable como parámetro de método no hace que su clase sea genérica, declarar y usar parámetros de tipo genérico es la forma en que lo hace genérico. respuesta

Quick-n-sucia: Usted está recibiendo el aviso porque está utilizando Comparable, que es una interfaz genérica, como un tipo de prima, en lugar de darle un argumentos de tipo específicos, como Comparable<String>.

Para solucionar este problema, crea add() genérica mediante la especificación de parámetros de tipo:

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

Pero esta solución rápida no van a resolver el problema general de que su clase es inseguro. Después de todo, ¿no deberían todos los objetos en su lista ser del mismo tipo? Este método add le permite incluir diferentes tipos en la misma lista. ¿Qué sucede cuando intentas comparar tipos heterogéneos (cómo haces compareTo una instancia de Object en una instancia de Number o una instancia de String)? Puede confiar en que el usuario de la clase haga lo correcto y se asegure de que solo incluyan 1 tipo de cosas en su lista, pero una clase genérica permitirá que el compilador aplique esta regla.

El mejor enfoque: La solución correcta es que la clase de lista ordenada debe probablemente sea genérica en general, al igual que las otras clases de colección en java.util.

Usted probablemente le gustaría algo así como:

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

Tenga en cuenta que cuando la clase es genérico, el método add utiliza el parámetro de tipo formal de clases en lugar de declarar su propio parámetro de tipo formal.

debe haber un montón de tutoriales en la web acerca de cómo crear una clase genérica, pero aquí hay un ejemplo rápido:

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; } 
} 
Cuestiones relacionadas