【问题标题】:Difference between Enumeration<? extends ZipEntry> and Enumeration<ZipEntry>?枚举<?扩展 ZipEntry> 和 Enumeration<ZipEntry>?
【发布时间】:2009-03-06 19:57:07
【问题描述】:

枚举 和 Enumeration?如果有,有什么区别?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    当你拥有其中一个时,你可以做什么并没有实际的区别,因为类型参数只用于“输出”位置。另一方面,您可以将什么用作作为其中之一。

    假设你有一个Enumeration&lt;JarEntry&gt; - 你不能把它传递给一个以Enumeration&lt;ZipEntry&gt; 作为参数之一的方法。您可以将它传递给采用Enumeration&lt;? extends ZipEntry&gt; 的方法。

    当你有一个在输入和输出位置都使用类型参数的类型时会更有趣——List&lt;T&gt; 是最明显的例子。以下是三个参数变化的方法示例。在每种情况下,我们都会尝试从列表中获取一项,然后再添加一项。

    // Very strict - only a genuine List<T> will do
    public void Foo(List<T> list)
    {
        T element = list.get(0); // Valid
        list.add(element); // Valid
    }
    
    // Lax in one way: allows any List that's a List of a type
    // derived from T.
    public void Foo(List<? extends T> list)
    {
        T element = list.get(0); // Valid
         // Invalid - this could be a list of a different type.
         // We don't want to add an Object to a List<String>
        list.add(element);   
    }
    
    // Lax in the other way: allows any List that's a List of a type
    // upwards in T's inheritance hierarchy
    public void Foo(List<? super T> list)
    {
        // Invalid - we could be asking a List<Object> for a String.
        T element = list.get(0);
        // Valid (assuming we get the element from somewhere)
        // the list must accept a new element of type T
        list.add(element);
    }
    

    更多详情,请阅读:

    【讨论】:

    • 类似 JarEntry 的 ZipEntrySubclass(ZipFile.entries 使用通配符的原因)?
    【解决方案2】:

    是的,直接来自sun generics tutorials 之一:

    这里的 Shape 是一个抽象类 三个子类:圆形、矩形、 和三角形。

    public void draw(List<Shape> shape) {
      for(Shape s: shape) {
        s.draw(this);
      }
    }
    

    值得注意的是draw() 方法只能在列表上调用 形状,不能在列表中调用 圆形、矩形和三角形的 例子。为了有方法 接受任何形状,它应该是 写法如下:

    public void draw(List<? extends Shape> shape) {
       // rest of the code is the same
    }
    

    【讨论】:

    • 这是 Jon Skeet 本周第二次在我面前得到答案。我建议我们将其称为 Skeeting。
    • 听起来不错。过去时会是什么?斯克特? “乔恩·斯基特又骗我了!” :)
    【解决方案3】:

    现在你刚刚离开并让我想起了我希望我们在 C# 世界中已经结束的事情。

    除了提供的链接之外,在这个问题的答案中,还有一些关于 C# 和 Java 的与此主题相关的很好的链接:Logic and its application to Collections.Generic and inheritance

    其中一个选择是:

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多