以下编译错误对我没有意义,我希望有人能够澄清:
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。
答案 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
,您可以使用任何您喜欢的字母。