Java 中菱形运算符 (<>) 的重点是什么? [英] What is the point of the diamond operator (<>) in Java?

查看:30
本文介绍了Java 中菱形运算符 (<>) 的重点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The diamond operator in java 7 allows code like the following:

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

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

However in Java 5/6, I can simply write:

List<String> list = new LinkedList();

我对类型擦除的理解是,这些是完全一样的.(无论如何,泛型在运行时会被删除).

My understanding of type erasure is that these are exactly the same. (The generic gets removed at runtime anyway).

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

Why bother with the diamond at all? What new functionality / type safety does it allow? If it doesn't yield any new functionality why do they mention it as a feature? Is my understanding of this concept flawed?

推荐答案

问题与

List<String> list = new LinkedList();

是在左侧,您使用的是 generic 类型 List 而在右侧,您使用的是 raw 输入 LinkedList.Java 中的原始类型实际上只是为了与前泛型代码兼容而存在,并且不应在新代码中使用,除非你绝对必须.

is that on the left hand side, you are using the generic type List<String> where on the right side you are using the raw type LinkedList. Raw types in Java effectively only exist for compatibility with pre-generics code and should never be used in new code unless you absolutely have to.

现在,如果 Java 从一开始就有泛型并且没有类型,例如 LinkedList,这些类型是在它拥有泛型之前最初创建的,那么它可能可以使构造函数用于如果可能,泛型类型会自动从赋值的左侧推断其类型参数.但它没有,为了向后兼容,它必须区别对待原始类型和泛型类型.这让他们需要创建一种略有不同但同样方便的方式来声明泛型对象的新实例,而无需重复其类型参数......菱形运算符.

Now, if Java had generics from the beginning and didn't have types, such as LinkedList, that were originally created before it had generics, it probably could have made it so that the constructor for a generic type automatically infers its type parameters from the left-hand side of the assignment if possible. But it didn't, and it must treat raw types and generic types differently for backwards compatibility. That leaves them needing to make a slightly different, but equally convenient, way of declaring a new instance of a generic object without having to repeat its type parameters... the diamond operator.

List 的原始示例而言;list = new LinkedList(),编译器会为该赋值生成警告,因为它必须这样做.考虑一下:

As far as your original example of List<String> list = new LinkedList(), the compiler generates a warning for that assignment because it must. Consider this:

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

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

Generics exist to provide compile-time protection against doing the wrong thing. In the above example, using the raw type means you don't get this protection and will get an error at runtime. This is why you should not use raw types.

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

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

The diamond operator, however, allows the right hand side of the assignment to be defined as a true generic instance with the same type parameters as the left side... without having to type those parameters again. It allows you to keep the safety of generics with almost the same effort as using the raw type.

我认为要理解的关键是原始类型(没有 <>)不能与泛型类型一样对待.当您声明原始类型时,您将无法获得泛型的任何好处和类型检查.您还必须记住,泛型是 Java 语言的通用部分...它们不仅适用于 Collection 的无参数构造函数!

I think the key thing to understand is that raw types (with no <>) cannot be treated the same as generic types. When you declare a raw type, you get none of the benefits and type checking of generics. You also have to keep in mind that generics are a general purpose part of the Java language... they don't just apply to the no-arg constructors of Collections!

这篇关于Java 中菱形运算符 (&lt;&gt;) 的重点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆