java 7中的diamond操作符允许如下代码:

List<String> list = new LinkedList<>();

然而在Java 5/6中,我可以简单地写:

List<String> list = new LinkedList();

我对类型擦除的理解是它们是完全相同的。(无论如何泛型都会在运行时被删除)。

为什么要为钻石费心呢?它允许哪些新的功能/类型安全?如果它没有产生任何新的功能,他们为什么要把它作为一个特性来提及呢?我对这个概念的理解有缺陷吗?


当前回答

菱形操作符的作用仅仅是在声明泛型类型时减少代码的类型。它对运行时没有任何影响。

如果在Java 5和Java 6中指定,唯一的区别是,

List<String> list = new ArrayList();

你必须指定@SuppressWarnings("unchecked")到列表中(否则你将得到一个未检查的强制转换警告)。我的理解是,diamond operator正试图让开发变得更容易。它与泛型的运行时执行完全没有关系。

其他回答

这一行导致[unchecked]警告:

List<String> list = new LinkedList();

因此,问题转换为:为什么[unchecked]警告仅在创建新集合时才自动抑制?

我认为,这比添加<>特性要困难得多。

UPD:我还认为,如果只在少数方面合法地使用原始类型,将会造成混乱。

你的理解有点瑕疵。菱形操作符是一个很好的特性,因为你不需要重复自己。在声明类型时定义一次类型是有意义的,但在右侧再次定义它就没有意义了。DRY原则。

现在来解释定义类型的所有细节。你是对的,类型在运行时被删除,但一旦你想从一个带有类型定义的List中检索一些东西,你就会把它作为你在声明列表时定义的类型返回,否则它将失去所有特定的功能,只有Object功能,除非你将检索到的对象转换为它的原始类型,这有时会非常棘手,并导致ClassCastException。

使用List<String> List = new LinkedList()将得到rawtype警告。

当你写List<String> List = new LinkedList();,编译器产生一个“unchecked”警告。您可以忽略它,但是如果您习惯了忽略这些警告,那么您也可能会错过通知您实际类型安全问题的警告。

所以,最好写一段不产生额外警告的代码,菱形运算符可以让你以一种方便的方式做到这一点,而没有不必要的重复。

菱形操作符的作用仅仅是在声明泛型类型时减少代码的类型。它对运行时没有任何影响。

如果在Java 5和Java 6中指定,唯一的区别是,

List<String> list = new ArrayList();

你必须指定@SuppressWarnings("unchecked")到列表中(否则你将得到一个未检查的强制转换警告)。我的理解是,diamond operator正试图让开发变得更容易。它与泛型的运行时执行完全没有关系。

理论上,菱形操作符可以通过保存重复的类型参数来编写更紧凑(且可读)的代码。实际上,这只是两个令人困惑的字符,什么都没有。为什么?

理智的程序员不会在新代码中使用原始类型。因此,编译器可以简单地假设不写类型参数就可以推断它们。 菱形操作符不提供类型信息,它只是告诉编译器,“它会没事的”。所以省略它也无妨。在菱形操作符合法的任何地方,编译器都可以“推断”它。

在我看来,有一种清晰而简单的方法将源代码标记为Java 7将比发明这些奇怪的东西更有用。在这样标记的代码中,原始类型可以被禁止而不会损失任何东西。

顺便说一句。但是,我认为不应该使用编译开关。程序文件的Java版本是文件的一个属性,根本没有选项。使用像这样微不足道的东西

package 7 com.example;

你可能更喜欢一些更复杂的东西,包括一个或多个花哨的关键字。它甚至允许将为不同Java版本编写的源代码一起编译,而不会出现任何问题。它将允许引入新的关键字(例如,“module”)或删除一些过时的特性(单个文件中多个非公共非嵌套类或其他)而不失去任何兼容性。