Java 7中的菱形运算符(<>)有什么意义? [英] What is the point of the diamond operator (<>) in Java 7?

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

问题描述

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<String>,而在右侧,您是在使用 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<String> 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);

但是,diamond运算符允许将赋值的右侧定义为真正的泛型实例,并具有与左侧相同的类型参数...而无需再次键入这些参数.它使您可以通过几乎保持与使用原始类型相同的努力来保持泛型的安全.

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 s的无参数构造函数!

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 7中的菱形运算符(&lt;&gt;)有什么意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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