简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM