Il s'agit d'un exemple concret d'une API de bibliothèque tierce, mais simplifié.
Compilé avec Oracle JDK 8u72
Considérez ces deux méthodes:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
Les deux rapportent un avertissement "casting non vérifié" - je comprends pourquoi. La chose qui me déroute est pourquoi puis-je appeler
Integer x = getCharSequence();
et il compile? Le compilateur doit savoir que cela Integer
n'implémente pas CharSequence
. L'appel à
Integer y = getString();
donne une erreur (comme prévu)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
Quelqu'un peut-il expliquer pourquoi ce comportement serait-il considéré comme valide? En quoi cela serait-il utile?
Le client ne sait pas que cet appel est dangereux - le code du client se compile sans avertissement. Pourquoi la compilation ne l'avertirait-elle pas / n'émettrait-elle pas une erreur?
En outre, en quoi est-il différent de cet exemple:
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
Essayer de réussir List<Integer>
donne une erreur, comme prévu:
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 cela est signalé comme une erreur, pourquoi Integer x = getCharSequence();
pas?
Integer x = getCharSequence();
sera compilé, mais le casting sur le RHSInteger x = (Integer) getCharSequence();
échoue à la compilation