3

关于 Java 中的泛型的另一个非常基本的问题,直接来自我的上一个问题。我们不是通过编写下面的代码两次向编译器提供相同的信息吗?为什么我们需要在左侧和右侧都提供?

List<Number> numbers = new ArrayList<Number>();

编辑:正如我在一些答案中看到的那样,它在 java 7 以后不再需要。但我想知道在 java 7 之前它不可能的原因是什么?

4

4 回答 4

4

引入了菱形运算符来删除这些冗余信息。

也请参阅此 SO 链接Java 7 中的菱形运算符有什么意义?

从我的阅读/理解来看,我认为泛型在 java 中做得不好。这 ?最后介绍的操作员是一个痛苦的工作。有擦除的事实表明,在我看来它是硬生生的。它可以完成工作,但我认为它可能会更好

于 2012-08-31T13:53:25.720 回答
3

因为 pre java 7 不支持构造函数的泛型类型推断。这在 java 7 中由菱形运算符解决。
您还可以编写通用工厂方法作为解决方法,例如:

 public static <T> List<T> createArrayList() {
      return new ArrayList<T>();
 }

然后

List<Integer> list = createArrayList();

这是有问题的,但有效。并且对于 Maps 和其他多参数泛型类型来说可能会得到很好的回报。


编辑:也许语言设计者决定不支持泛型类型推断,因为他们实现了具有类型擦除的泛型。我认为另一个值得商榷的决定......否则,不要认为在早期的 Java 版本中反对这个特性有任何严重的理由。(根据彼得劳里的附录,它仍然不存在。)

于 2012-08-31T13:53:15.993 回答
1

因为一个是参考,一个是实现。该行的左侧是设置存储实例化变量的引用。由于 Java 使用“运行时类型擦除”来实现泛型,因此除了引用分配之外的任何代码都无法知道泛型参数是什么分配的。

编辑-我不知道J7的变化(我有点过时了:))-看起来他们解决了这个问题。

于 2012-08-31T13:54:09.433 回答
0

As well as the reasons described in the other answers, the argument on the right side in this example does not need to be exactly the same as the left one. Example:

List<? extends Calendar> cals = new ArrayList<GregorianCalendar>();
于 2012-08-31T13:54:59.747 回答