问题:
从子类访问时,参数化类的对象被视为非泛型对象。我该如何克服这一切?
详细信息:
考虑一个基类:
public class MyBaseClass {
protected List<Number> numbers = new ArrayList<Number>();
public MyBaseClass(){
//...
}
}现在,让我们扩展这个类:
public class MyDerivedClass extends MyBaseClass {
public void addSomething() {
numbers.add(25.0f); //Warning about type-safety here
}
}在派生类中,numbers对象被视为原始类型。警告是:
类型安全性:方法add(Object)属于原始类型列表。对泛型类型列表的引用应该参数化。
如果我自己尝试添加类型参数,就会得到一个编译错误:
numbers.<Number>add(25.0f); //Error here我看到的错误是:
类型列表的add(Number)方法不是泛型的;它不能用参数进行参数化。
但是,如果我将两个类都放在同一个Java源文件中,那么这个问题就没有了。从一开始就没有警告。这是一个例子来说明这个问题。
在我的实际应用程序中,我希望能够从派生类中的List中获取元素,并对它们执行特定于类的操作,而不必首先将检索到的对象转换为适当的类型。
我怀疑问题是因为类型擦除,但我想不出如何解决这个问题。
编辑:
我在Fedora 16上使用Eclipse3.7.2和Oracle 1.6.0_30,编译器遵从性设置设置为1.6。如前所述,如果我将两个类放置在同一个.java文件中,则不会看到警告。只有当我将它们放在不同的文件中时才能看到。
我可以通过定义直接在父类中的list对象上操作的所有方法来解决这个问题;并使用派生类中的方法。
但我还是很好奇为什么我会看到这个警告。这是一个解决办法:
在MyBaseClass中:
protected void addNumberToList(Number num){
numbers.add(num);
}然后在派生类中:
public void addSomething() {
addNumberToList(25.0f);
}类似地,所有直接操作List对象的操作都可以在基类中。
发布于 2012-06-21 07:58:46
真正的基类是泛型的,但是您的子类继承自它的原始类型:
public class MyBaseClass<X> {
protected List<Number> numbers = new ArrayList<Number>();
public List<Number> getNumbers() {
return numbers;
}
}
public class MyDerivedClass extends MyBaseClass {
public void addSomething() {
numbers.add(25.0f);
}
}JLS第4.8节说,成员访问将被视为原始类型。这意味着numbers被视为raw,因此出现了警告。解决方案是将超级类型参数化:
public class MyDerivedClass extends MyBaseClass<TypeArgumentsHere>发布于 2012-06-21 07:17:20
我使用Eclipse,您的代码编写得很好,没有警告或错误。但我认为您应该提供protected/public方法,而不是公开实例变量。
public class MyBaseClass {
protected List<Number> numbers = new ArrayList<Number>();
public List<Number> getNumbers() {
return numbers;
}
}
public class MyDerivedClass extends MyBaseClass {
public void addSomething() {
getNumbers().add(25.0f);
}
}https://stackoverflow.com/questions/11133214
复制相似问题