Java generics ковариация
У меня возникли проблемы с пониманием следующей статьи:
http://www.ibm.com/developerworks/java/library/j-jtp01255.html
Под
Дженерики не ковариантны
автор утверждает,
Поскольку ln - это List, добавление Поплавок ему кажется вполне законным. Но если бы они были псевдонимы с ли, то это сломает обещание по типу безопасности неявный в определении li - что это список целых чисел, который почему общие типы не могут быть ковариантны.
Я не могу понять, в какой части
"если бы они были псевдонимы с ли". Что означает автор по псевдониму? (Ссылка?). Фрагмент кода выше цитируемой строки, кажется, иллюстрирует ЧТО является незаконным в Java, а не ПОЧЕМУ. Было бы очень полезно, если бы кто-нибудь мог объяснить пример.
Спасибо заранее.
Ответы
Ответ 1
List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));
В Java Integer наследует от Number (java.lang.Number)
, поэтому интуитивно, все, что является Integer (java.lang.Integer)
, также является числом, но то, что указывает эта статья, заключается в том, что с generics это не работает, потому что учитывая, что Например, вы можете положить float (который является числом) в List<Integer>
, что является незаконным, поскольку float не является целым числом.
Вывод: Дженерики не ковариантны.
Примечание.. Я рекомендую вам прочитать "Эффективное Java" (2-е издание). Глава 5: Общие.
Ответ 2
Если вы можете сделать что-то вроде этого:
List<Float> foo;
List<Object> bar;
foo = new ArrayList<Float>();
bar = foo;
foo.add(1.0f);
bar.add("Hello");
все пошло бы ОЧЕНЬ неправильно. В этом примере панель является псевдонимом для foo, и если вы можете это сделать, вы потеряете безопасность типа, которая является основной причиной существования дженериков.
Ответ 3
public class vechicle {
void drive(){
}
}
class car extends vechicle{
//Covariance
vechicle getObject(){
return new car();
}
//contravariance
car getmyObject(){
return (car) new vechicle();
}
}