2011-07-20 25 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; 
       } 
    } 
} 

编辑:错别字。 编辑2:完成这个例子

+0

这取决于笼子的声明和它的添加方法。它只是一个集合的子类? – Affe

+0

你在第一行遗漏了构造函数调用的括号,在'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>。你不能添加任何东西,因为它可能是任何特定的笼子。

如果你想添加TCage它必须是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

相关问题