Почему Список <Число> не является подтипом Списка <Объект>?

Игры С Целью - который разрабатывают инструменты Коллективного разума как Luis von Ahn и его команда, возможно, были мечтой до 1980, но не было широко развернутой сети с миллионами доступных людей и потребность (например, reCAPTCHA), чтобы на самом деле заставить ее произойти.

9
задан Kip 6 August 2009 в 17:51
поделиться

5 ответов

Что вы делаете в пример «без универсальных» - это приведение, которое дает понять, что вы делаете что-то небезопасное для типов. Эквивалент для дженериков будет:

Object o;
List<Double> d;
String s;

o = s;
d.add((Double) o);

Который ведет себя одинаково (компилируется, но не работает во время выполнения). Причина запрета поведения, о котором вы спрашиваете, заключается в том, что оно допускает неявные небезопасные по типу действия, которые гораздо труднее заметить в коде. Например:

public void Foo(List<Object> list, Object obj) {
  list.add(obj);
}

Это выглядит прекрасно и безопасно по типам, пока вы не назовете его так:

List<Double> list_d;
String s;

Foo(list_d, s);

Что также выглядит типобезопасным, потому что вы, как вызывающий, не обязательно знаете, что Foo собирается делать со своими параметрами.

] Итак, в этом случае у вас есть два, казалось бы, типобезопасных бита кода, которые вместе оказываются типо-небезопасными. Это плохо, потому что это скрыто, и поэтому его трудно избежать и труднее отладить.

11
ответ дан 4 December 2019 в 07:48
поделиться

Подумайте, если бы это было ...

List<Integer> nums = new ArrayList<Integer>();
List<Object> objs = nums
objs.add("Oh no!");
int x = nums.get(0); //throws ClassCastException

Вы могли бы добавить в список что-нибудь, относящееся к родительскому типу, которое может отличаться от того, как оно было объявлено ранее, что, как показывает пример выше, вызывает всевозможные проблемы. Таким образом, это запрещено.

9
ответ дан 4 December 2019 в 07:48
поделиться

По сути, здесь есть два измерения абстракции: абстракция списка и абстракция его содержимого. Совершенно нормально варьировать абстракцию списка - например, сказать, что это LinkedList или ArrayList, - но нельзя еще больше ограничивать содержимое, например: This (список, содержащий объекты) является (связанным списком, который содержит только числа). Поскольку любая ссылка, которая знает его как (список, содержащий объекты), в соответствии с контрактом своего типа понимает что он может содержать любой объект.

Это сильно отличается от того, что вы делали в коде, не являющемся универсальным, где вы сказали: относитесь к этой String, как если бы она была Double. Вместо этого вы пытаетесь сказать: относитесь к этому (списку, который содержит только числа) как к (списку, который содержит что угодно). И это не так, и компилятор может обнаружить это, поэтому он не позволит вам избежать наказания за это.

3
ответ дан 4 December 2019 в 07:48
поделиться

Они не являются подтипами друг друга из-за того, как работают дженерики. Вы хотите объявить свою функцию следующим образом:

public void wahey(List<?> list) {}

Затем она примет Список всего, что расширяет Object. Вы также можете:

public void wahey(List<? extends Number> list) {}

Это позволит вам получить списки чего-то, что является подклассом Number.

Я бы порекомендовал вам взять копию "Java Generics and Collections" Мориса Нафталина и Филипа Вадлера.

4
ответ дан 4 December 2019 в 07:48
поделиться

«То, что мы здесь делаем, по сути то же самое, только это пройдет проверки во время компиляции и терпят неудачу только при время выполнения. Версия со списками не будет compile. "

То, что вы наблюдаете, имеет смысл, если учесть, что основная цель дженериков Java - добиться сбоя несовместимости типов во время компиляции, а не во время выполнения.

Из java.sun. com

Generics позволяет сообщить тип коллекции компилятору, чтобы он мог быть проверил. Как только компилятор узнает тип элемента коллекции, компилятор может проверить, что вы использовали сбор последовательно и может вставьте правильные приведения значений удаляются из коллекции.

1
ответ дан 4 December 2019 в 07:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: