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

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

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

List<String> list = new LinkedList();

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

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

推荐答案

问题在于

List<String> list = new LinkedList();

左边是genericList<String>,右边是rawLinkedList.Java中的原始类型实际上只是为了与泛型之前的代码兼容而存在的,除非

现在,如果Java从一开始就有泛型,并且没有最初在有泛型之前创建的类型,比如LinkedList,那么它可能已经创建了泛型类型,以便泛型类型的构造函数在可能的情况下从赋值的左侧自动推断其类型参数.但事实并非如此,它必须以不同的方式对待原始类型和泛型类型,以实现向后兼容性.这就使得他们需要用一种slightly different但同样方便的方式来声明泛型对象的新实例,而不必重复其类型参数...钻石操作员.

对于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);

泛型的存在是为了提供编译时保护,防止出错.在上面的示例中,使用raw类型意味着您没有得到这种保护,并且在运行时会出现错误.这就是为什么不应该使用原始类型.

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

然而,菱形运算符允许将赋值的右侧定义为真正的泛型实例,其类型参数与左侧相同...无需再次输入这些参数.它允许你像使用原始类型一样努力保持泛型的安全性.

我认为需要理解的关键是,原始类型(没有<>)不能与泛型类型一样对待.当您声明一个原始类型时,您不会得到泛型的好处和类型判断.你也要记住generics are a general purpose part of the Java language...它们不仅仅适用于Collections的无参数构造函数!

Java相关问答推荐

Mat. n_Delete()和Mat. n_release的区别

Spring boot:Bean和动态扩展器

弹簧靴和龙目岛

工件部署期间出错[Tomcat 8.5.45]

Java FX中的河内之塔游戏-在游戏完全解决之前什么都不会显示

当我已经安装了其他版本的Java时,如何在Mac OSX 14.3.1上安装Java 6?

FALSE:它应该在什么时候使用?

如何调整工作时间日历中的时间

将带有js文件的 bootstrap 程序导入maven项目时出错

Java构造函数分支

%This内置函数示例

Kotlin Val是否提供了与Java最终版相同的可见性保证?

如何在JavaFX循环中完美地制作一个AudioClip/MediaPlayer?

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

错误:未找到扩展元素在JBossEAP 7.2中安装FUSE时出错

寻找Thread.sky()方法的清晰度

具有多个模式的DateTimeForMatter的LocalDate.parse失败

如何使用外部函数从Java中获取C++ struct 的返回值&;内存API

如何在JSP中从select中获取值并将其放入另一个select

using case default on switch语句返回;预览特征切换中的模式匹配仅在源级别20及以上的情况下可用;