简体   繁体   English

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

[英]Unknown compilation error with generics in Java

The following compilation error makes no sense to me, and I was hoping someone would be able to elucidate: 以下编译错误对我没有意义,我希望有人能够阐明:

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();
}   

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

In order to get the above code to compile, I had to replace the entries declaration to use the generics <? extends ZipEntry> 为了得到上面的代码进行编译,我不得不替换entries声明来使用泛型<? extends ZipEntry> <? extends ZipEntry> . <? extends ZipEntry> Why do I have to do this? 为什么我要这样做? Doesn't ZipEntry extend ZipEntry? ZipEntry不扩展ZipEntry吗? (Isn't that vacuously true?) Why does the compiler complain about that? (这不是真的吗?)为什么编译器抱怨这个?

If it helps, I'm using Java 7.03 with Eclipse Indigo 64 bit. 如果它有帮助,我使用Java 7.03和Eclipse Indigo 64位。

ZipFile.entries() returns an enumeration of extended ZipEntry types but is not confined to ZipEntry itself so you need to use: ZipFile.entries()返回扩展ZipEntry类型的枚举,但不限于ZipEntry本身,因此您需要使用:

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

This allows for other types such as JarEntry objects to be used in ZipEntry Enumerations. 这允许在ZipEntry枚举中使用其他类型,例如JarEntry对象。

The problem is that ZipFile.entries() returns Enumeration<? extends ZipFile> 问题是ZipFile.entries()返回Enumeration<? extends ZipFile> Enumeration<? extends ZipFile> . Enumeration<? extends ZipFile>

From here : 这里

Generics are not covariant 泛型不是协变的

"While you might find it helpful to think of collections as being an abstraction of arrays, they have some special properties that collections do not. Arrays in the Java language are covariant -- which means that if Integer extends Number (which it does), then not only is an Integer also a Number, but an Integer[] is also a Number[], and you are free to pass or assign an Integer[] where a Number[] is called for. (More formally, if Number is a supertype of Integer, then Number[] is a supertype of Integer[].) You might think the same is true of generic types as well -- that List is a supertype of List, and that you can pass a List where a List is expected. Unfortunately, it doesn't work that way." “虽然你可能会发现将集合视为数组的抽象是有帮助的,但它们有一些特殊的属性,集合不具备这些特性.Java语言中的数组是协变的 - 这意味着如果Integer扩展了Number(它确实如此),那么不仅Integer也是一个数字,而且Integer []也是一个Number [],你可以自由地传递或分配一个调用Number []的Integer []。(更正式的是,如果是一个超类型的Integer,然后Number []是一个Integer []的超类型。)你可能会认为泛型类型也是如此 - List是List的超类型,你可以传递一个List的List预计。不幸的是,它不会这样。“

Enumeration<? extends ZipFile> Enumeration<? extends ZipFile> does not mean a collection of any type that extends ZipFile... instead it is a collection containing a specific type extending ZipFile. Enumeration<? extends ZipFile>并不意味着Enumeration<? extends ZipFile>的任何类型的集合......而是一个包含扩展ZipFile的特定类型的集合。 Even though it is legal to implicitly cast from say, JarFile to ZipFile ( ZipFile z = new JarFile(); l it is not legal to cast from Enumeration<JarFile> to Enumeration<ZipFile> . 即使将SayFile隐式地转换为ZipFile( ZipFile z = new JarFile(); l从Enumeration<JarFile>Enumeration<ZipFile>也是不合法的。

If you look closely(source code) , it return Enumeration<ZipEntry> only as below: 如果仔细观察(源代码) ,它只返回Enumeration<ZipEntry> ,如下所示:

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

But return type is declared as public Enumeration<? extends ZipEntry> entries() { 但是返回类型被声明为public Enumeration<? extends ZipEntry> entries() { public Enumeration<? extends ZipEntry> entries() { to relax the restriction on the return type. public Enumeration<? extends ZipEntry> entries() {放宽对返回类型的限制 If you wish to override entries() method through your custom subclass of Zipfile , you may want to use one of the subclasses of the ZipEntry as return type from the same method ie ZipEntry 如果您希望通过Zipfile的自定义子类覆盖entries()方法,您可能希望使用ZipEntry一个子类作为返回类型来自同一方法,即ZipEntry

If you don't want to use generics, you may want to write as : 如果您不想使用泛型,您可能希望编写为:

  @SuppressWarnings("rawtypes")
  Enumeration entries = zip_file.entries();
Make sure that the file exists and is accessible, you can also try this 

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

Use <Z extends ZipEntry> and replace all of the ? 使用<Z extends ZipEntry>并替换所有? instances in you methods if you have any, with Z . 你有方法中的实例,如果你有任何, Z You are not limited to Z , you can use any letter you like. 您不限于Z ,您可以使用任何您喜欢的字母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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