有没有办法将动物添加到笼子里? :)
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;
}
}
}
编辑:错别字。
编辑2:完成示例
答案 0 :(得分: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;
}
}
}
}
答案 1 :(得分: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
}
从技术上讲,该方法并非严格必要,但您可以轻松查看此代码的问题。 Cage<?>
可以是Cage<String>
或Cage<Anything>
。您无法添加任何内容,因为它可能是任何特定的Cage。
如果您要将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
}
}
}