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