method - java 1.8 generics
Java "llamada no seleccionada a compareTo(T) como miembro del tipo sin formato java.lang.Comparable" (3)
Debe "verificar" o definir el objeto Comparable de la siguiente manera:
add(Comparable<Object> obj)
Estoy tratando de implementar una lista ordenada como un simple ejercicio en Java. Para hacerlo genérico, tengo un add(Comparable obj)
así que puedo usarlo con cualquier clase que implemente la interfaz de Comparable.
Pero, cuando uso obj.compareTo(...)
en cualquier parte del código, obtengo una "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 averiguar cómo deshacerme de ese molesto mensaje.
¿Alguna pista?
En esencia, esta advertencia dice que el objeto Comparable
no puede compararse 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, para poder usar la Comparable<T>
correctamente, debe hacer que su lista ordenada sea genérica, para expresar la restricción de que su lista almacena objetos que pueden compararse entre sí, algo como esto:
public class SortedList<T extends Comparable<? super T>> {
public void add(T obj) { ... }
...
}
Usar 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 rápida y sucia: está recibiendo la advertencia porque está utilizando Comparable
, que es una interfaz genérica, como un tipo sin formato, en lugar de darle un tipo de argumentos específicos, como Comparable<String>
.
Para solucionar esto, haga que add()
genérico especificando parámetros de tipo:
<T extends Comparable<? super T>> add(T obj) { ... }
Pero esta solución rápida no solucionará el problema general de que su clase no es segura. Después de todo, ¿no deberían ser del mismo tipo todos los objetos en su lista? Este método de add
permite aún diferentes tipos en la misma lista. ¿Qué sucede cuando intentas comparar tipos heterogéneos (cómo comparas una instancia de Object
con una instancia de Number
o una instancia de String)? Puede depender del usuario de la clase para hacer lo correcto y asegurarse de que solo pegue 1 tipo de cosa en su lista, pero una clase genérica permitirá que el compilador aplique esta regla.
El mejor enfoque: la solución adecuada es que su clase de lista ordenada probablemente debería ser genérica en general, al igual que las otras clases de colección en java.util
.
Probablemente te gustaría algo 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érica, el método add
usa el parámetro de tipo formal de clases en lugar de declarar su propio parámetro de tipo formal.
Debería haber muchos tutoriales en la web sobre 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; }
}