Использование общих коллекций в аргументах - PullRequest
3 голосов
/ 16 июня 2011

Допустим, у вас есть:

public interface A {}

public class B implements A {}

public class C {
  void foo (List<A>) {}
}

public class Test {
  //Declaration one
  List<A> x = new List<A>();

  //Declaration two
  List<A> x = new List<B>();

  B b = new B();
  x.add(b);


  new C().foo(x);
}

Теперь, очевидно, декларация 1 - это правильный способ сделать это, и вы получите ошибку компиляции в декларации 2. Я хотел бы знать, хотя, почему Java выбирает для обеспечения безопасности типов именно таким образом; если список кошек по-прежнему является списком животных, почему метод, ожидающий, что список животных блокируется при получении группы кошек?

Любопытство, больше всего на свете - и возможность улучшить мои знания.

Ура, Дэйв.

Ответы [ 3 ]

9 голосов
/ 16 июня 2011

Почему метод, ожидающий список животных, отказывается при приеме группы кошек?

Потому что вы можете добавить в этот список любое животное, а не только кошек. Это может привести к списку кошек, содержащих собаку, например:

I think there's a spy aming us …

Вызывающий все еще думает, что это список кошек, и собака умирает, когда вызывающая сторона пытается заставить их упасть на ноги при падении.

9 голосов
/ 16 июня 2011

Обобщения Java не являются ковариантными .Если бы вы могли сделать это:

ArrayList<Animal> x = new ArrayList<Cat>();

, то вы могли бы сделать:

x.add(new Dog());

, что нарушает концепцию, согласно которой ArrayList<Cat> может содержать только Cat объекты (илиобъекты подкласса).

Подробнее об этом читайте в следующих статьях: Теория и практика Java: общие сведения получили .

0 голосов
/ 16 июня 2011

Используйте «extends» вместо класса напрямую:

List<? extends A>x;

Если вы используете только класс как общий, то все элементы должны быть только этого класса.

...