为什么我们需要两次提供通用信息?

时间:2012-08-31 13:51:36

标签: java generics language-design

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

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

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

4 个答案:

答案 0 :(得分:4)

正在引入钻石操作员,可以删除这些冗余信息。

同时查看此SO链接What is the point of the diamond operator in Java 7?

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

答案 1 :(得分:3)

因为pre java 7不支持构造函数的泛型类型推断。这是由钻石运营商在java 7中解决的。
您也可以编写通用工厂方法作为解决方法,如:

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

然后

List<Integer> list = createArrayList();

哪个有问题但有效。对于地图和其他多论证泛型类型而言,也许还不错。


编辑:也许语言设计者决定不支持泛型类型推断,因为他们实现了类型擦除的泛型。我认为另一个值得怀疑的决定......否则不要认为在早期的java版本中有任何严重的理由反对这个功能。 (而Peter Lawrey的附录中,它仍然没有出现。)

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

除了其他答案中描述的原因外,本例中右侧的参数不需要与左侧的参数完全相同。例如:

List<? extends Calendar> cals = new ArrayList<GregorianCalendar>();