通配符和泛型错误

时间:2009-03-07 00:00:47

标签: java

下面的代码是一次性的,一个失败的想法让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");
    }
}

错误是:

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

1 个答案:

答案 0 :(得分:5)

构造参数化类型时,不能指定通配符。这是正确的语法:

iteratable  = new IterableEnumeration<ZipEntry>(enumeration);

正如您所指出的,使用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;
  }

  ...

class EnumerationIterator<T>
  implements Iterator<T>
{

  private final Enumeration<? extends T> enumeration;

  public EnumerationIterator(final Enumeration<? extends T> e)
  {
    enumeration = e;
  }

  ...

这些更改基本上意味着,IterableEnumeration<T>可以与Enumeration的任何子类型的T进行协作。”