Java中的泛型有未知的编译错误

时间:2012-10-26 23:49:38

标签: java eclipse compiler-errors eclipse-indigo

以下编译错误对我没有意义,我希望有人能够澄清:

static public void main(String args[]) throws ZipException, IOException
{
    File file = new File("C:\\temp");
    ZipFile zip_file = new ZipFile(file);
    Enumeration<ZipEntry> entries = zip_file.entries();
}   

我收到以下错误:Type mismatch: cannot convert from Enumeration<capture#1-of ? extends ZipEntry> to Enumeration<ZipEntry>

为了使上面的代码能够编译,我必须替换entries声明来使用泛型<? extends ZipEntry>。为什么我要这样做? ZipEntry不扩展ZipEntry吗? (这不是真的吗?)为什么编译器会抱怨这个?

如果有帮助,我正在使用带有Eclipse Indigo 64位的Java 7.03。

5 个答案:

答案 0 :(得分:4)

ZipFile.entries()会返回扩展ZipEntry类型的枚举,但不仅限于ZipEntry,因此您需要使用:

Enumeration<? extends ZipEntry> entries = zip_file.entries();

这允许在JarEntry枚举中使用其他类型的ZipEntry个对象。

答案 1 :(得分:2)

问题是ZipFile.entries()会返回Enumeration<? extends ZipFile>

来自here

泛型不协变

“虽然你可能会发现将集合视为数组的抽象是有帮助的,但它们有一些特殊的属性,集合不具备.Java语言中的数组是协变的 - 这意味着如果Integer扩展了Number(它是然后,不仅Integer也是一个数字,而且Integer []也是一个Number [],你可以自由地传递或分配一个调用Number []的Integer []。(更正式地说,如果Number是Integer的超类型,则Number []是Integer []的超类型。)您可能认为泛型类型也是如此 - List是List的超类型,并且您可以传递List预计列表的位置。不幸的是,它不会那样工作。“

Enumeration<? extends ZipFile>并不意味着扩展ZipFile的任何类型的集合......而是包含扩展ZipFile的 特定 类型的集合。即使将SayFile隐式地转换为ZipFile(ZipFile z = new JarFile(); l,从Enumeration<JarFile>转换为Enumeration<ZipFile>也是不合法的。

答案 2 :(得分:2)

如果仔细观察(源代码),则仅返回Enumeration<ZipEntry>,如下所示:

     return new Enumeration<ZipEntry>() {
            private int i = 0;
            public boolean hasMoreElements() {
            .....
            .....

但是返回类型被声明为public Enumeration<? extends ZipEntry> entries() {放宽对返回类型的限制。如果您希望通过entries()的自定义子类覆盖Zipfile方法,则可能需要使用 ZipEntry 的子类之一作为返回类型同样的方法,即ZipEntry

如果您不想使用泛型,可能需要写为:

  @SuppressWarnings("rawtypes")
  Enumeration entries = zip_file.entries();

答案 3 :(得分:1)

Make sure that the file exists and is accessible, you can also try this 

Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip_file.entries(); 

答案 4 :(得分:1)

使用<Z extends ZipEntry>并替换您方法中的所有?个实例(如果有)Z。您不限于Z,您可以使用任何您喜欢的字母。