public class Boxcar<S extends Things> {
public ArrayList<S> contents = new ArrayList<S>(); //an arraylist of things
public static void main(String [] args){
Boxcar test = new Boxcar();
test.addContents(new Person("239-235-2535", "Ronald", 36)); //works 100%
}
public Boxcar(Things type, int maxElements){
this.type = type;
boxcarId = boxcarIdCount;
boxcarIdCount++;
this.maxElements = maxElements;
}
public void addContents(S thing) {
contents.add(thing);
}
...
}//end boxcar class
public class Person implements Things {
int age;
String govtId, name;
public Person(String govtId, String name, int age){
this.govtId = govtId;
this.name = name;
this.age = age;
}//end Consrtructor
public void load(ArrayList<Boxcar<?>> train){
Person dude = new Person("239-235-235", "Ronald", 36);
train.get(i).addContents(dude); // won't compile
}
...
}//end Person class
public interface Things {
public void load(ArrayList<Boxcar<?>> train, String [] params);
}//end interface Things
public class Train {
ArrayList<Boxcar<?>> train = new ArrayList<Boxcar<?>>();
public void load(Things thing, String [] params){
thing.load(train, params);
}
...
}
在上面的代码中,方法addContents在Boxcar类中执行时似乎工作正常。但是,当从Person类调用时,它的行为方式完全不同。
造成这种情况的原因是什么?如何解决?
答案 0 :(得分:1)
Java编译器不允许在您的案例中访问未绑定参数化类型Boxcar<?>
的引用上的方法,因为类型未知。
您应该定义通配符的边界并按如下方式使用它:
public void load(ArrayList<Boxcar<? super Things>> train)
{
Person dude = new Person("239-235-235", "Ronald", 36);
train.get(0).addContents(dude);
}
答案 1 :(得分:1)
它无法编译的原因是train
参数是未知类型的Boxcar
列表。实际上,这意味着您有一个未定义类型的contents
列表,并且您尝试在其中放置Person
,这不是类型安全操作。想象一下,如果按如下方式执行加载方法会发生什么:
person.load(new ArrayList<Boxcar<Integer>>());
要修复它,您应该按如下方式修复方法的签名:
public void load(ArrayList<Boxcar<? super Things>> train){
...
}
此外,您应该避免将泛型与原始类型混合,就像在main方法中那样。而不是:
Boxcar test = new Boxcar();
您应该使用:
Boxcar<Things> test = new Boxcar<Things>();
否则,即使代码编译(带有警告),它也可能在运行时因类强制转换异常而失败。