【问题标题】:Generics lower bound ('super') issue? [duplicate]泛型下限(“超级”)问题? [复制]
【发布时间】:2013-01-02 19:38:41
【问题描述】:

可能重复:
java generics super keyword

我无法将我的知识与以下示例程序联系起来。请参阅下面的示例程序,然后我的疑问就在该程序下方。

import java.util.*;
class A { }
class B extends A { }
class C extends B { }

public class sampleprog {

    public static void main(String[] args) {

        List<? super A> list1 = new ArrayList<A>();
        list1.add(new A());//valid. ok
        list1.add(new B());//valid, why? it is not super to A?
        list1.add(new C());//valid, why? it is not super to A?

        List<? super B> list2 = new ArrayList<A>();
        list2.add(new A());//not valid. why? it is also super to B!!!
        list2.add(new B());
        list2.add(new C());

        List<? super C> list3 = new ArrayList<C>();
        list3.add(new A());//not valid, why? It is super to A so should be valid!!!
        list3.add(new B());//not valid, why? It is super to A so should be valid!!!
        list3.add(new C());
    }
}

我的疑惑: - 据我所知? super T 表示您可以添加的任何类都超级到T 但这里的输出不同?甚至子类也成功添加,这完全令人困惑。 - 输出与列表初始化 (List&lt;? super C&gt; list3 = new ArrayList&lt;C&gt;();) 没有什么不同。在这个初始化中,我分配了AB的列表,输出是一样的!

请消除我的疑虑。

【问题讨论】:

    标签: java generics


    【解决方案1】:

    "? super T" 表示您可以添加的任何类必须是 T 或其子类的实例。

    所以List&lt;? super C&gt; list3 = new ArrayList&lt;C&gt;(); 在 list3 中,您可以添加 C 类或其子类实例 (SomeClass extends C) 的实例。

    父对象列表可以有自己的子对象和子对象,但为子类创建的列表不能有其父对象。希望你现在清楚了。

    【讨论】:

    • 是的,现在有了“? super T”的新定义,但它是 scjp kathy sierra 中给出的定义“当你使用 super ...> 语法时,你是在告诉编译器,您可以接受 super 右侧的类型或其任何超类型,因为——这是使它工作的关键部分——”在第 619 页上!!!为什么她说超类型而你说子类型?
    • 稍后让我澄清一下。
    【解决方案2】:

    List&lt;? super B&gt; 表示

    List<? super B> list1 = new ArrayList<A>();
    List<? super B> list1 = new ArrayList<B>();
    

    是允许的。 ArrayList&lt;A&gt;ArrayList&lt;B&gt; 的超级,不是吗?我们可以将BC 添加到ArrayList&lt;A&gt;ArrayList&lt;B> 中吗?我们可以。我们可以添加A 吗?仅指向ArrayList&lt;A&gt;.List&lt;? super B&gt; 也允许指向ArrayList&lt;B&gt;。所以我们不能将A's 添加到List&lt;? super B&gt;

    【讨论】:

    • 很好的解释,但ArrayList&lt;A&gt; 不是 超级于ArrayList&lt;B&gt; - 你一定是说A 超级于B
    【解决方案3】:

    如果我们在泛型声明中使用? super,则引用可以指向相同的泛型集合或超泛型集合。所以在这种情况下,所有通过 IS-A 测试的东西都是有效的。

    【讨论】:

    • 但是“?super B”明确提到任何对B超的类。所以A和其他类应该是有效的但不是C?但根据输出,C 是有效的!!!
    【解决方案4】:

    投票支持@us2012 的评论。

    • 对于List&lt;? super A&gt;

      类型是A。A、B、C都是A的子类型,所以可以添加。

    • 对于List&lt;? super B&gt;

      类型可以是A,B。B和C都是A或B的子类型。 想想List&lt;? super B&gt; list2 = new ArrayList&lt;A/B&gt;()的区别

    • 对于List&lt;? super C&gt;

      类型可以是A、B、C。所以只有C是A、B或C的子类型。

    例如,Machine -> Car -> SportsCar。对于List&lt;? super Machine&gt;,无论是Machine、Car、SportsCar,都是Machine,所以添加是安全的。

    【讨论】:

    • 对不起。还是不清楚。例如。列表。类型可以是 A、B。(右)但它的意思是“B 和 C 都是扩展 A 和 B 的子类型”!!!
    • “B 和 C 都是扩展 A 和 B 的子类型”表示:List&lt;? super B&gt; 可以是 List&lt;A&gt;List&lt;B&gt;。 B和C都可以在List&lt;A&gt;List&lt;B&gt;中添加,但是A不行,A不能在List&lt;B&gt;中添加。
    • 现在清除。但我只有一个疑问,这就是我们考虑子类的原因吗? 'super' 的意思是'任何超类而不是子类'!!!
    猜你喜欢
    • 2018-04-10
    • 2010-10-10
    • 2013-04-02
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多