知优码

您现在的位置是:首页 > 开源项目 > 项目经验

项目经验

Java7的菱形运算符(<>)的作用和使用

2020-12-24项目经验
Java7的菱形运算符(<>)的作用和使用

一、概述

Java 7中的菱形运算符允许如下代码:

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

但是,在Java 5/6中,我可以简单地编写:

List<String> list = new LinkedList();

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

为什么要使用钻石呢?它允许哪些新功能/类型安全?如果它没有产生任何新功能,为什么他们将其称为新功能?我对这个概念的理解有缺陷吗?

二、详解

问题在

List<String> list = new LinkedList();

是在左侧,您使用的是通用类型List<String>,而在右侧,您使用的是原始类型LinkedListJava中的原始类型实际上仅存在于与泛型代码的兼容性,并且除非绝对必要,否则决不能在新代码中使用。

现在,如果Java从一开始就具有泛型并且没有诸如之类的类型,而该类型LinkedList最初是在具有泛型之前创建的,则它可能已经做到了,这样泛型类型的构造函数会自动从左侧推断出其类型参数-尽可能在作业的另一侧。但事实并非如此,为了向后兼容,必须对原始类型和泛型类型进行不同的处理。这使得他们需要采取一种稍微不同但同样方便的方式来声明泛型对象的新实例,而不必重复其类型参数……菱形运算符。

就您的原始示例而言List<String> list = new LinkedList(),编译器会为该分配生成警告,因为它必须这样做。考虑一下:

List<String> strings = ... // some list that contains some strings

// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);

存在泛型以提供编译时保护以防止做错事。在上面的示例中,使用原始类型意味着您没有获得此保护,并且在运行时会收到错误消息。这就是为什么您不应该使用原始类型的原因。

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

但是,菱形运算符允许将赋值的右侧定义为具有与左侧相同类型参数的真正的泛型实例,而不必再次键入这些参数。它使您可以与使用原始类型几乎相同的工作来保持泛型的安全

我认为关键要理解的是,原始类型(不带<>)不能与泛型类型相同。声明原始类型时,不会获得任何好处和泛型的类型检查。您还必须记住,泛型是Java语言的通用部分……它们不仅适用于Collections的无参数构造函数