[英]Generics - Eclipse compiler issues a warning, javac gives an error
Assuming I have the following classes in an application: 假设我在应用程序中有以下类:
A base class: 基类:
public abstract class Animal {}
A subclass 一个子类
public class Dog extends Animal {
public void bark() {
System.out.println("woof");
}
}
A class from a third party library: 来自第三方图书馆的课程:
public class ThirdPartyLibrary /* *cough* Hibernate *cough* */{
public List find() {
return new ArrayList() {
// fetched from the db in the actual app of course
{
add(new Dog());
add(new Dog());
add(new Dog());
}
};
}
}
And a utility class: 和实用类:
public class Util {
public <E extends Animal> E findUnique(List<E> animals) {
return animals.isEmpty() ? null : animals.get(0);
}
/**
* @param args
*/
public static void main(String[] args) {
Dog d = new Util().findUnique(new ThirdPartyLibrary().find());
d.bark();
}
}
The eclipse compiler issues the following warnings: eclipse编译器发出以下警告:
- Type safety: The expression of type List needs unchecked conversion to conform to List 类型安全:类型List的表达式需要未经检查的转换以符合List
- Type safety: Unchecked invocation findUnique(List) of the generic method findUnique(List) of type Util 类型安全:未选中调用类型为Util的泛型方法findUnique(List)的findUnique(List)
But the build fails when compiling with Sun's javac with the error: 但是使用Sun的javac编译错误时构建失败:
incompatible types
[javac] found : Animal
[javac] required: Dog
[javac] Dog d = new Util().findUnique(new ThirdPartyLibrary().find());
[javac] ^
Is there something else I can do to make this code compile in javac, apart from an explicit cast to (List<Dog>)
before the call to findUnique? 除了在调用findUnique之前显式转换为(List<Dog>)
之外,我还能做些什么来使这个代码在javac中编译?
No, there's nothing else you can do, and you must have something fishy going on in Eclipse, because Eclipse wouldn't be able to compile that (as Java code), either. 不,你无能为力,而且你必须在Eclipse中有一些可疑的东西,因为Eclipse也无法编译它(如Java代码)。 Since the list you pass to findUnique() is a raw type, the compiler can't determine what the E
should be in public <E extends Animal> E findUnique(List<E> animals)
. 由于传递给findUnique()的列表是原始类型,因此编译器无法确定E
应该在public <E extends Animal> E findUnique(List<E> animals)
。 Therefore E
essentially becomes ?
因此E
基本上变成?
, and what you're trying to do is basically this: ,你要做的基本上是这样的:
List<? extends Animal> l = new ArrayList<Animal>();
Dog dog = l.get(0);
It should be obvious that that can never work. 很明显,这永远不会奏效。 The only way to get close to making this work is to add a method argument that makes E
have a distinct value. 接近使这项工作的唯一方法是添加一个方法参数,使E
具有不同的值。 Something like this would work: 像这样的东西会起作用:
public <E extends Animal> E findUnique(List animals, Class<E> type) {
return animals.isEmpty() ? null : (E) animals.get(0);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.