【问题标题】:Instantiation of Generic object with wildcard使用通配符实例化通用对象
【发布时间】:2016-10-18 17:39:30
【问题描述】:

我有课

public class OrderedBox<T> {}    


编译器不允许创建这样的成员/局部变量。

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();
List<? extends T> testItems2 = new ArrayList<? extends T>();

它在运行时是可以理解的原因,它不保证将插入对象的类型(以 T 为上限)并且会违反类型安全。

但它允许创建像这样的成员/局部变量。 为什么以及如何允许这样做?

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();



笔记: 我在浏览http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html时有这个疑问

可能重复:
Creating new generic object with wildcard
Generics wildcard instantiation

但这两个问题都提供了 2 个选项编译失败的原因。 我不明白为什么以及如何允许最后一个 1。

【问题讨论】:

  • 两个问题:您运行的是什么版本的 Java,为什么不使用可以解决此问题的菱形 &lt;&gt; 运算符?
  • 您提到的链接“使用通配符创建新的通用对象”上的第一个答案解释了您第一次被禁止的原因(因为您没有说明将创建什么类 testItems1 对象)以及为什么您被允许第二次(因为你告诉列表应该是 OrderedBox 类型)
  • @Makoto,第一名:Java7。第二:谢谢, 解决了。但我的问题是为什么它可以解决它?
  • @NareshJoshi 但未指定 OrderedBox 的类型推断
  • 是的,但是对于创建列表对象,您不需要它,对于创建列表对象,您只需要要存储在 OrderedBox 列表中的对象类型,但同样的情况是不适用于您的第一个场景。

标签: java generics bounded-wildcard


【解决方案1】:

您发布的第二个 SO 问题实际上解释了单行变化的答案:Generics wildcard instantiation

One-liner 确实声明OrderedBox 类型,但不创建它的实例。

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();

这表示您将拥有一个 OrderedBox,但没有说明是哪一个。 尝试创建像

这样的实例时会遇到麻烦
testItems.add(new OrderedBox<? extends T>())

因为那个时候,你会修复类型。

【讨论】:

  • 你的解释真的很有帮助。我试过了,它就像你提到的那样工作。但我想知道它在运行时是如何工作的:)。编辑问题
  • Java 编译器执行type erasure(这是要查找的关键字)。所以它在运行时被转换成OrderedBox&lt;Object&gt;,理论上你可以把任何东西放进去。但是编译器会阻止你事先这样做。
【解决方案2】:

您的列表对象是 bag a,您可以在其中保存许多 OrderedBox 对象

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();

OrderedBox 在编译时包含什么并不重要,当您尝试将对象插入该列表时,使用这种语法会导致问题。

你应该在声明一个类时使用泛型(通配符),但是在为那个类创建对象时你应该像

private List<OrderedBox<Object>> testItems = new ArrayList<OrderedBox<Object>>();

编译器不允许

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();

因为这里你没有说,OrderedBox的类型是什么,你也应该在这里具体。

【讨论】:

    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2010-09-15
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    相关资源
    最近更新 更多