Это пример из стороннего библиотечного API, но упрощенный.
Скомпилировано с Oracle JDK 8u72
Рассмотрим эти два метода:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
Оба сообщают о предупреждении «непроверенный актерский состав» - я понимаю, почему. Меня сбивает с толку то, почему я могу позвонить
Integer x = getCharSequence();
а это компилируется? Компилятор должен знать, что Integerне реализует CharSequence. Призыв к
Integer y = getString();
выдает ошибку (как и ожидалось)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
Может кто-нибудь объяснить, почему это поведение считается действительным? Как это будет полезно?
Клиент не знает, что этот вызов небезопасен - код клиента компилируется без предупреждения. Почему компиляция не предупредит об этом / не выдаст ошибку?
Кроме того, чем он отличается от этого примера:
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
Попытка пройти List<Integer>дает ошибку, как и ожидалось:
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
Если это сообщается как ошибка, почему Integer x = getCharSequence();нет?
Integer x = getCharSequence();будет компилироваться, но кастинг на RHSInteger x = (Integer) getCharSequence();не скомпилируется