ковариация - PullRequest
       57

ковариация

20 голосов
/ 18 апреля 2010

У меня проблемы с пониманием следующей статьи: http://www.ibm.com/developerworks/java/library/j-jtp01255.html

Под

Обобщения не ковариантны

Автор утверждает,

Поскольку ln - это список, добавление Поплавок к нему кажется совершенно законным. Но если бы я был связан с li, то это нарушит обещание безопасности типа подразумевается в определении li - что это список целых чисел, который Вот почему универсальные типы не могут быть ковариантны.

Я не могу понять ту часть, где говорится «Если бы я был псевдонимом li». Что автор подразумевает под псевдонимом? (Ссылка?). Фрагмент кода над строкой в ​​кавычках, кажется, иллюстрирует, ЧТО является недопустимым в java, а не ПОЧЕМУ. Было бы очень полезно для меня, если бы кто-то мог объяснить на примере. Заранее спасибо.

Ответы [ 3 ]

41 голосов
/ 18 апреля 2010
List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

В Java Integer наследует от Number (java.lang.Number), поэтому интуитивно все, что является целым числом (java.lang.Integer), также является числом, но в этой статье указывается, что с генериками это не работает, потому что, учитывая, что Например, вы можете в конечном итоге поместить число с плавающей точкой в ​​число List<Integer>, что недопустимо, поскольку число с плавающей точкой не является целым числом.

Вывод: Обобщения не ковариантны.

Примечание: Я рекомендую вам прочитать Effective Java (2nd Edition) Глава 5: Общие положения.

8 голосов
/ 18 апреля 2010

Если бы вы могли сделать что-то вроде этого:

List<Float> foo;
List<Object> bar;

foo = new ArrayList<Float>();
bar = foo;

foo.add(1.0f);
bar.add("Hello");

все пошло бы ОЧЕНЬ неправильно. В этом примере bar является псевдонимом для foo, и если бы вы могли это сделать, вы бы потеряли безопасность типов, которая является основной причиной существования обобщенных типов.

0 голосов
/ 05 марта 2014
public class vechicle {
void drive(){
}
}
class car extends vechicle{
        //Covariance
    vechicle getObject(){
        return new car();
    }
        //contravariance
    car getmyObject(){
        return (car) new vechicle(); 
    }
}
...