2012-08-31 35 views
3

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

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

编辑:当我在它,它不需要任何更多的Java 7中起了一些答案看看。但我想知道java 7之前不可能的原因是什么?

回答

3

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

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

然后

List<Integer> list = createArrayList(); 

这是值得商榷的,但工程。也许为地图和其他多重论证的泛型类型带来好处。


到编辑:也许是语言的设计者决定不支持泛型类型推断,因为他们实现与类型擦除泛型。另一个可疑的决定,我认为...否则,不要认为在早期的Java版本中有任何反对这个特性的严重原因。 (并且通过Peter Lawrey的附录,它仍然不存在。)

+1

从技术上讲''''不会进行类型推断,它只是不检查如果你编写'List numbers = new ArrayList <>();'它确定但是'列表 numbers = new ArrayList <>(){};'不是因为它需要知道创建类的实际类型。 –

+0

@PeterLawrey:谢谢你的补充。 – zeller

4

正在引入钻石操作员来移除这些冗余信息。

看到这个链接SO以及What is the point of the diamond operator in Java 7?

从我读/理解我不认为泛型是做到了在Java中。这个?最后介绍的操作员是一件很痛苦的工作。有删除的事实表明,在我看来,它是鞋子。它可以完成这项工作,但我认为它可能会更好

+0

请参阅编辑。我想了解java 7之前的问题是什么,这迫使设计人员以这种方式进行设计。 – Geek

1

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

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

0

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

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