Este es un ejemplo del mundo real de una API de biblioteca de terceros, pero simplificado.
Compilado con Oracle JDK 8u72
Considere estos dos métodos:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
Ambos informan una advertencia de "lanzamiento no verificado". Entiendo por qué. Lo que me desconcierta es por qué puedo llamar
Integer x = getCharSequence();
y se compila? El compilador debe saber que Integer
no se implementa CharSequence
. La llamada a
Integer y = getString();
da un error (como se esperaba)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
¿Alguien puede explicar por qué este comportamiento se consideraría válido? ¿Cómo sería útil?
El cliente no sabe que esta llamada no es segura: el código del cliente se compila sin previo aviso. ¿Por qué la compilación no advierte sobre eso / emite un error?
Además, ¿en qué se diferencia de este ejemplo?
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
Intentar pasar List<Integer>
da un error, como se esperaba:
method doCharSequence in class generic.GenericTest cannot be applied to given types; required: java.util.List<X> found: java.util.List<java.lang.Integer> reason: inference variable X has incompatible bounds equality constraints: java.lang.Integer upper bounds: java.lang.CharSequence
Si eso se informa como un error, ¿por qué Integer x = getCharSequence();
no?
Integer x = getCharSequence();
se compilará, pero el lanzamiento en el RHSInteger x = (Integer) getCharSequence();
falla la compilación