type - Java y genéricos. ¿No es 0 un número?
java generics parameter (5)
0 es un int
, pero dado que su método devuelve un objeto, se autoboxeará en un Integer
. El problema es que el compilador no permite devolver un Integer
donde esté permitida cualquier subclase de Número . Eso es simplemente porque puedes ejemplificar tu clase como
new Zero<Double>()
y en este caso, devolver Integer
no sería compatible con el tipo de retorno esperado: Double
.
¿Qué es lo que me falta sobre este fragmento de código?
public class Zero<N extends Number> {
public N zero() {
return new Integer(0);
}
}
Dice:
Tipo no coincidente: no se puede convertir de entero a N
¡Gracias!
Actualizar He cambiado el fragmento para usar un número entero. Lo mismo sucede. Y sucede incluso cuando se crea una subclase anónima de Number
. ¿Podría ser Eclipse el que tenga fallas al respecto?
Cuando ''N'' extiende ''Número'', ''N'' se convierte en una especialización de ''Número'' y no puede asignar una instancia de una clase base a una variable de referencia de su especialización (problema de actualización). Esto también es válido mientras regresas. No se puede devolver una instancia de clase base utilizando el tipo de especialización.
El problema con su código es que Java necesita poder confirmar que el tipo de devolución de la función necesita ser convertible a N extends Number
para cualquier N
Entonces, en particular, si tuviera que instanciar la clase con un Double
, como en
Zero<Double> z = new Zero<Double>();
z.zero();
Te encontrarás con problemas, porque zero
dice que devuelve un Double
pero en realidad devuelve un Integer
. El error de tipo indica que al compilador le preocupa que ocurra algo como esto.
A mi leal saber y entender, no hay una buena forma de hacerlo en Java porque los genéricos se implementan mediante borrado; no puede saber cuál es el tipo de argumento.
Mientras que un Entero es un Número, un Entero podría no ser compatible con N, que puede ser cualquier subclase de Número.
No se garantiza que Integer sea una superclase de N, por lo que no puede simplemente establecer un valor Integer para un objeto de tipo N.
Piénselo de esta manera: si alguien instancia Zero<N>
como Zero<Double>
, la clase se convierte en:
public class Zero {
public Double zero() {
return new Integer(0);
}
}
que obviamente no es válido
Además, tampoco se puede return 0
porque, de la misma manera, el compilador no puede saber cómo convertirlo a N. (El compilador solo puede autoboxar los tipos que conoce, pero al usar los genéricos amplió los tipos disponibles para incluir también implementaciones personalizadas de Number).