泛型 - Eclipse 编译器发出警告,javac 给出错误

Jes*_*run 2 java

假设我在应用程序中有以下类:

一个基类:

public abstract class Animal {}
Run Code Online (Sandbox Code Playgroud)

一个子类

public class Dog extends Animal {

public void bark() {
    System.out.println("woof");
}
}
Run Code Online (Sandbox Code Playgroud)

来自第三方库的类:

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());
        }
    };
}
}
Run Code Online (Sandbox Code Playgroud)

还有一个实用程序类:

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();
}   
}
Run Code Online (Sandbox Code Playgroud)

eclipse 编译器发出以下警告:

  • 类型安全:List 类型的表达式需要未经检查的转换才能符合 List
  • Type safety: Unchecked invocation findUnique(List) of the generic method findUnique(List) of type Util

But the build fails when compiling with Sun's javac with the error:

 incompatible types
    [javac] found   : Animal
    [javac] required: Dog
    [javac] Dog d = new Util().findUnique(new ThirdPartyLibrary().find());
    [javac]                          ^
Run Code Online (Sandbox Code Playgroud)

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?

Rya*_*art 5

不,您无能为力,而且您必须在 Eclipse 中进行一些可疑的操作,因为 Eclipse 也无法编译它(作为 Java 代码)。既然你传递给findUnique()是一个原始类型列表中,编译器不能确定什么E应该是public <E extends Animal> E findUnique(List<E> animals)。因此E基本上变成了?,而你要做的基本上是这样的:

List<? extends Animal> l = new ArrayList<Animal>();
Dog dog = l.get(0);
Run Code Online (Sandbox Code Playgroud)

很明显,这永远行不通。接近完成这项工作的唯一方法是添加一个E具有不同值的方法参数。像这样的事情会起作用:

public <E extends Animal> E findUnique(List animals, Class<E> type) {
    return animals.isEmpty() ? null : (E) animals.get(0);
}
Run Code Online (Sandbox Code Playgroud)