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