下面的代码是一次性的,一个失败的想法让Enumeration在新的foreach循环中工作,但是我想让它编译,因为我一直遇到泛型和外卡的问题.无论出于何种原因,我都看不出如何修复它.
那么,需要进行哪些更改才能进行编译?
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Main
{
private ZipFile zipFile;
public Set<String> entries()
{
final Set<String> names;
final Enumeration<? extends ZipEntry> enumeration;
final IterableEnumeration<? extends ZipEntry> iteratable;
names = new HashSet<String>();
// zipFile.entries() returns "Enumeration<? extends ZipEntry>"
enumeration = zipFile.entries();
// this line won't compile
iteratable = new IterableEnumeration<? extends ZipEntry>(enumeration);
for(final ZipEntry entry : iteratable)
{
if(!(entry.isDirectory()))
{
names.add(entry.getName());
}
}
return (names);
}
}
class IterableEnumeration<T>
implements Iterable<T>
{
private final Enumeration<T> enumeration;
public IterableEnumeration(final Enumeration<T> e)
{
enumeration = e;
}
public Iterator<T> iterator()
{
final EnumerationIterator<T> iterator;
// yeah cannot do this since an Iterable is supposed to work multiple times on the same object and Enumeration is descructive...
iterator = new EnumerationIterator<T>(enumeration);
return (iterator);
}
}
class EnumerationIterator<T>
implements Iterator<T>
{
private final Enumeration<T> enumeration;
public EnumerationIterator(final Enumeration<T> e)
{
enumeration = e;
}
public boolean hasNext()
{
return (enumeration.hasMoreElements());
}
public T next()
{
return (enumeration.nextElement());
}
public void remove()
{
throw new UnsupportedOperationException("Cannt remove via an Enumeration");
}
}
Run Code Online (Sandbox Code Playgroud)
错误是:
Main.java:26: unexpected type
found : ? extends java.util.zip.ZipEntry
required: class or interface without bounds
iteratable = new IterableEnumeration<? extends ZipEntry>(enumeration);
^
1 error
Run Code Online (Sandbox Code Playgroud)
构造参数化类型时,不能指定通配符.这是正确的语法:
iteratable = new IterableEnumeration<ZipEntry>(enumeration);
Run Code Online (Sandbox Code Playgroud)
正如您所指出的那样,实现Iterable一个Enumeration因为Enumeration是一次性使用很困难,而代码可以依赖于Iterable创建任意数量的新鲜Iterator对象.您可以在增强的for循环中安全地使用它,但将这样的传递Iterable给任何其他方法是不安全的.
奥斯卡是对的,上述改变是不够的.我忽略了底层enumeration是" ? extends ZipEntry" 的事实.此外,进行以下更改:
class IterableEnumeration<T>
implements Iterable<T>
{
private final Enumeration<? extends T> enumeration;
public IterableEnumeration(final Enumeration<? extends T> e)
{
enumeration = e;
}
...
Run Code Online (Sandbox Code Playgroud)
和
class EnumerationIterator<T>
implements Iterator<T>
{
private final Enumeration<? extends T> enumeration;
public EnumerationIterator(final Enumeration<? extends T> e)
{
enumeration = e;
}
...
Run Code Online (Sandbox Code Playgroud)
这些变化基本上意味着" IterableEnumeration<T>可以与Enumeration任何子类型协作T."