Почему добавление подкласса типа в коллекцию недопустимо?

Учитывая этот фрагмент кода

    //Creates a list of List numbers
    List<List<Number>> num = new ArrayList<List<Number>>();
    //Creates a list of List doubles
    List<List<Double>> doub = new ArrayList<List<Double>>();
    //List of doubles
    List<Double> d = new ArrayList<Double>();
    d.add(2.5);
    d.add(2.6);
    doub.add(d);

    num.add(d);//This code will not compile

Почему это num.add(сомнение) не будет разрешено? не List<List<Number>> супер тип List<List<Double>>?

4 ответа

Решение

Генерическое наследование мало отличается от нашего понимания наследования. Если вы хотите использовать типы подклассов, вам нужно определить границы ( подстановочные знаки) с использованием extends (или) super в обобщениях.

Вы пытаетесь добавить список списков в список, который принимает список. (не после редактирования я вижу)

Или, может быть, немного менее запутанным:

Your num list can only add List<Number>, you are trying to add a List<List<Double>>.

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

Если вы определите num следующим образом:

    List<List<? extends Number>> num = new ArrayList<List<? extends Number>>();

Тогда вы сможете сделать это:

    num.add(d);

но нет:

    num.add(doub);

List<Double> не имеет ничего общего с List<Number> насколько компиляр обеспокоен List<> часть.

Следовательно List<List<Double>> не наследуется от List<List<Number>> это два совершенно разных типа в системе Java Generics. Это не extends отношения, как при создании классов.

Учитывая заявленные типы, doub.add(d) а также num.add(doub) подразумевает противоречивое поведение add(), Если doub.add(d) работает, я не ожидал num.add(doub) к тому же.

Возможно, вы хотели проверить

num.add(d)

вместо

num.add(doub)

?

Другие вопросы по тегам