为什么类型需要定义两次?

时间:2014-06-26 21:41:48

标签: java generics

目前这是我们定义类型的方式:如果在Type - Integer下面。声明类型两次看起来多余。

FindMiddleStack<Integer> fm = new FindMiddleStack<Integer>();

我猜java可能已经足够聪明了 FindMiddleStack<Integer> fm = new FindMiddleStack(); 要么 FindMiddleStack fm = new FindMiddleStack<Integer>();

为什么他们不做简单的路线(即只在左边或右边定义一次类型,或声明)?

3 个答案:

答案 0 :(得分:5)

因为这是一个特殊情况并使语言复杂化。

FindMiddleStack<Integer> fm = ...声明一个名为FindMiddleStack<Integer>的{​​{1}}类型的变量,其初始值为fm评估的值。它并不关心...是什么。

...创建new FindMiddleStack<Integer>()。它并不关心如何使用FindMiddleStack<Integer>

在Java 7中,他们确实付出了额外的努力来实现它,你可以这样做:

FindMiddleStack<Integer>

答案 1 :(得分:3)

Java使用diamond operator,因为Java 7,足够智能

FindMiddleStack<Integer> fm = new FindMiddleStack<>();

请注意使用此方法:

FindMiddleStack<Integer> fm = new FindMiddleStack();

您正在使用原始类型初始化您的泛型类,这会引发警告,但您可以使用fm中的Integer元素,编译器会检查它。

另一种方式:

FindMiddleStack fm = new FindMiddleStack<Integer>();

您有一个使用泛型初始化的原始类,它也会引发警告。但是这种情况比第一种情况更糟,因为编译器无法检查将在fm中使用的通用元素。

答案 2 :(得分:0)

因为在语义上你正在创建两个不同的东西,其类型恰好匹配。

在左侧创建引用,在右侧创建一个运算符,赋值运算符将一个连接到另一个。

此外,引用的类型可以与对象的类型不同。 E.g。

List<? extends Number> list = new ArrayList<Integer>();

如果您采用了只写一次类型的解决方案,那么您将如何处理此问题?

然而,Java 7中的语义糖以避免在意图相同的情况下编写类型两次是受欢迎的,即使它可能令人困惑。例如,如果以下工作:

List<? extends Number> list = new ArrayList<Integer>();
list = new ArrayList<>();

然后列表指向

ArrayList<Integer> 

ArrayList<Number>

我不知道上面的代码片段是否适用于Java 7,但是如果它确实如此,我对于在代码的一部分中更改引用类型可以改变在其他地方实例化的对象类型的想法感到不舒服创建非常脆弱的代码。