为什么Java 7钻石运算符不能与匿名类一起使用? [英] Why can't Java 7 diamond operator be used with anonymous classes?

查看:195
本文介绍了为什么Java 7钻石运算符不能与匿名类一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个试图实例化一些 List 的Java代码:

Consider this Java code which attempts to instantiate some Lists:

List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<>();
List<String> list3 = new ArrayList<String>() { };
List<String> list4 = new ArrayList<>() { };
List<String> list5 = new ArrayList<Integer>() { };

list1 list2 很简单; list2 使用Java 7中的新菱形运算符来减少不必要的类型参数重复。

list1 and list2 are straightforward; list2 uses the new diamond operator in Java 7 to reduce unnecessary repetition of the type parameters.

list3 是使用匿名类的 list1 的变体,可能会覆盖 ArrayList

list3 is a variation on list1 using an anonymous class, potentially to override some methods of ArrayList.

list4 尝试使用菱形运算符,类似于 list2 ,但这是编译错误,消息'<>'不能与匿名类一起使用。

list4 attempts to use the diamond operator, similar to list2, but this is a compile error, with the message '<>' cannot be used with anonymous classes.

list5 产生错误,证明编译器知道实际需要什么类型。错误消息是类型不匹配:无法从新的ArrayList (){}转换为List

list5 produces an error that proves the compiler knows what type is actually needed. The error message is Type mismatch: cannot convert from new ArrayList<Integer>(){} to List<String>

所以,使用声明 list4 ,为什么不能将菱形运算符与匿名类一起使用?这里有一个类似的问题,并且已接受答案包含来自 JSR-334 :

So, with the declaration of list4, why can't the diamond operator be used with anonymous classes? There is a similar question here with an accepted answer that contains the following explanation from JSR-334:


不支持将菱形与匿名内部类一起使用,因为
这样做通常需要扩展类文件
签名属性表示不可表示的类型,事实上JVM
更改。

Using diamond with anonymous inner classes is not supported since doing so in general would require extensions to the class file signature attribute to represent non-denotable types, a de facto JVM change.

我需要一些帮助理解那个推理。为什么显式类型与相同且明显容易推断的类型需要在生成的类文件中有任何差异? 一般这样做会涵盖哪些困难的用例?

I need some help understanding that reasoning. Why would an explicit type versus the identical and apparently easily inferred type require any difference in the resulting class file? What difficult use case would be covered by "doing so in general"?

推荐答案

这是在Project Coin邮件列表。实质上(强调我的):

This was discussed on the "Project Coin" mailing list. In substance (emphasis mine):


在内部,Java编译器在一组更丰富的类型上运行,而不是
那些可以是在Java程序中明确写下来。无法在Java程序中编写的
编译器内部类型是
,称为非可表示类型。不可表示的类型可以作为钻石使用的推理的结果
出现。 因此,不支持使用带有
匿名内部类的菱形,因为这样做通常会
需要扩展类文件签名属性来表示
不可表示的类型,事实上的JVM更改
。未来的
平台版本可以在创建匿名
内部类时允许使用菱形,只要推断类型是可表示的。

Internally, a Java compiler operates over a richer set of types than those that can be written down explicitly in a Java program. The compiler-internal types which cannot be written in a Java program are called non-denotable types. Non-denotable types can occur as the result of the inference used by diamond. Therefore, using diamond with anonymous inner classes is not supported since doing so in general would require extensions to the class file signature attribute to represent non-denotable types, a de facto JVM change. It is feasible that future platform versions could allow use of diamond when creating an anonymous inner class as long as the inferred type was denotable.

请注意,它在Java 8中也不受支持,但将作为Java 9中的新功能包含在内(铣削项目硬币)。

Note that it is not supported in Java 8 either but will be included as a new feature in Java 9 (Item 3 of "Milling Project Coin").

这篇关于为什么Java 7钻石运算符不能与匿名类一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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