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(); 
    }
}