2011-07-20 2 views
0

есть ли способ добавить животное в клетку? :)Добавление общего значения в общий контейнер неизвестного типа

public class Cage<T> extends ArrayList<T> { 
    public final String name = "foo"; 
} 

public Zoo { 
    List<? extends Cage<?>> zooCages= new ArrayList<Cage<?>>(); 

    public <T> void addAnimal(String name, T animal){ 
      for(Cage<?> c : zooCages) 
       if(c.name.equals(name)){ 
        c.add(animal);  //compile error 
        return; 
       } 
    } 
} 

EDIT: Опечатки. EDIT 2: завершить пример

+0

Это скорее зависит от декларации клетки и ее метода добавления. Это просто подкласс коллекции? – Affe

+0

Вам не хватает скобок для вызова конструктора в строке 1. и точка с запятой после 'c.add (animal)'. –

ответ

1

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

Cage<?> cage1 = new Cage<Integer>(); 
Cage<?> cage2 = new Cage<String>(); 
Cage<?> cage3 = new Cage<T>(); 

someMethod(cage1); 
someMethod(cage2); 
someMethod(cage3); 

public void someMethod(Cage<?> cage) { 
    cage.add(1);    // Will not compile 
    cage.add("A String");  // Will not compile 
    cage.add(someValueOfTypeT); // Will not compile 
} 

Технически метод не является строго необходимым, но вы можете легко увидеть проблему с этим кодом. A Cage<?> может быть Cage<String> или Cage<Anything>. Вы ничего не можете добавить к нему, потому что это может быть любой конкретный Кейдж.

Если вы хотите добавить T к Cage он должен быть Cage<T> или Cage<? super T>. Один из способов сделать это можно:

public class Zoo<T> { 
    private List<? extends Cage<? super T>> cages = new ArrayList<>(); 

    public void addAnimal(String cageName, T animal) { 
    for(Cage<? super T> cage : cages) { 
     // Now you can add animal to a cage 
    } 
    } 
} 
2

(. Я предполагаю, что Cage коллекция)

Вы концептуальную ошибку здесь.

c объявлен в цикле foreach как Cage<?>, то есть клетке, которая принимает неопределенный тип. Вы пытаетесь добавить к нему объект типа T, но нет оснований полагать, что c может содержать объекты типа T.

Дополнительную информацию о шаблоне * см. В http://download.oracle.com/javase/tutorial/java/generics/wildcards.html.

Возможно, вы хотели, чтобы все клетки в классе содержали один и тот же (произвольный) тип T. В этом случае весь охватывающий класс должен принимать параметр типа. Например:

import java.util.*; 

public class Main<T> { 
    private class Cage extends ArrayList<T> { 
     public final String name = "foo"; 
    } 

    List<? extends Cage> zooCages = new ArrayList<Cage>(); 

    public void addAnimal(String name, T animal) { 
     for(Cage c : zooCages) { 
      if(c.name.equals(name)) { 
       c.add(animal); 
       return; 
      } 
     } 
    } 
} 
+0

спасибо, см. Полный пример выше, – user853080

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