2013-12-05 2 views
2

Я пытаюсь поместить объект подкласса в список, но я не могу этого сделать из-за ошибки компилятора, упомянутой в качестве комментария. Может кто-нибудь указать, что это правильный способ сделать это на Java?Добавить родительский объект в список <? extends Parent> - Java

public class Animal { } 

class Util { 

    private Map<Class<? extends Animal>, List<? extends Animal>> animalListMap; 

    public void registerAnimal(Class<? extends Animal> animalClass, Animal animalObject) { 

     if (animalListMap.containsKey(animalClass)) { 
      //Append to the existing List 
      List<? extends Animal> animalList = animalListMap.get(animalObject); 
      animalList.add(animalObject); //COMPILE ERROR- The method add(capture#3-of ? extends Animal) in the type List<capture#3-of ? extends Animal> is not applicable for the arguments (Animal) 
     } else { 
      // and the new entry 
      List<Animal> vos = new ArrayList<Animal>(); 
      vos.add(animalObject); 
      animalListMap.put(animalClass, vos); 
     } 
    } 
} 
+1

В качестве побочного примечания 'animalListMap.get (animalObject)' должно быть 'animalListMap.get (animalClass)'. –

+0

Вы передаете экземпляр объекта, вместо объекта класса –

+0

animalListMap.get (animalObject); должен быть animalListMap.get (animalClass); –

ответ

3

Вы ничего не можете добавить в свой аккаунт List<? extends Animal>. List<? extends Animal> означает «список I-don-t-know-what-but-something-that-extends-Animal», который может быть List<Animal> или List<Cat>.

Если вы могли бы, этот код будет составлять:

 

List dogs = new ArrayList(); 
List animals = dogs; 
animals.add(new Cat()); 
Dog dog = dogs.get(0); 

Вы можете, однако, изменить List<? extends Animal> к List<Animal>, который, кажется, что вы хотите здесь.

1

Вы объявляете

List<? extends Animal> animalList = animalListMap.get(animalObject); 

? extends Animal является подстановочным ограниченной Animal класса. Так animalListMap.get(animalObject); может возвращать List<Donkey>, List<Mouse>, List<Pikachu>, предполагая Donkey, Mouse и Pikachu были все суб классы Animal. Однако с помощью подстановочного знака вы сообщаете компилятору, что вас не волнует, что такое фактический тип, если он является подтипом Animal.

Поскольку вы не знаете, что это такое, вы фактически ничего не можете добавить (кроме null). Если то, что вы получили назад, было List<Pikachu>, но animalObject фактически ссылался на объект Donkey, у вас были бы проблемы по линии. Вот почему компилятор не позволяет компилировать этот код.

Если у вас есть List<Animal>, то вы можете добавить любой объект, у которого есть тип или тип родителя Animal.

0

Потому что animalList - это список чего-то, что распространяется на животных, но не может быть конкретно животным. Другими словами, это может быть ограничено некоторым подтипом животного, например, у вас может быть список Лев, Тигр или Медведь (о мой!).

Как хорошо, ваш код подвержен странностям, рассмотрят следующий призывающий пример кода:

myUtil.registerAnimal(Zebra.class, new Tiger()); 
+0

«Потому что animalList - это список чего-то, что распространяется на животных, но не может быть животным». incorrecto. Конечно, они все животные, но могут быть и другие ограничения, что это должен быть определенный тип животного, как показывает ваш пример. – RAY

+0

@ RAY пояснил, что бит – Taylor

+0

Чтобы устранить странность, я предлагаю обобщить метод: – RAY

0

Вы должны изменить эту декларацию,

private Map<Class<? extends Animal>, List<? extends Animal>> animalListMap; 

, если вы собираетесь добавить животное в список ,

List<? extends Animal>> инструктирует complier не позволять добавлять что-либо, кроме нулевого в этот список.

Смежные вопросы