2012-03-01 50 views
16

我观看了Oracle OTN虚拟事件:Java SE和JavaFX 2.0(2012年2月28日),并在谈到新的钻石操作员(即Map<String, List<String>> myMap = new HashMap<>();的事)时提到,它的实现并不像人们想象的那么简单,因为它不是简单的代币替换。Java 7钻石操作员:为什么难以实施?

我的问题是为什么?为什么不能这样实现,就像从变量声明中取出字符串并将其放入钻石运算符中一样?

+3

Upvoted。为什么我们甚至需要一个操作员呢? – Croo 2012-03-01 09:17:25

回答

14

我也没有实现它,所以我只能猜测。

但是通常这些事情比他们看起来更复杂的原因是第一次检查只看最常见的(或最公开的)用例。在这种情况下,这是你提到的那个。在理论上,应该很容易明确指出,在编译器中实现应该相当容易。

然而,钻石经营者(这在技术上不是运营商的方式)能够以不同的方式使用,也:

someMethodWithGenericArguments(new HashMap<>()); 
new SomeGenericClass(new HashMap<>()); 
T foo = new SomethingRelatedToT<>(); // where T is a generic type parameter 

在这种情况下,简单的令牌替换显然不再起作用,你需要涉及实际类型分析的实际类型推断(即它与完全不同的抽象级别,因为简单的代币替换会是)。

+0

谢谢,我看到这些确实是更复杂的情况。第一种情况引发了如下问题:如果'someMethodWithGenericArguments()'重载了˙Map˙和'Map '..在这种情况下,菱形操作。似乎对我完全模糊.. – jabal 2012-03-01 08:15:07

+0

@jabal:试试吧!既然'Map '和'Map '具有相同的擦除操作('Map'),那么您就不能有一个方法的这两个覆盖。 – 2012-03-01 08:17:29

2

Java不能做的事(许多语言都有)是基于用法的暗示类型。即Java并不意味着基于它如何使用的需求类型。

例如

Type a = b; 

类型的ab类型是独立的,任何假设都是基于a的类型进行约b

MethodHandles正在显示出支持这一点的迹象。返回类型的使用可以基于上下文,但这是一个运行时功能。

总之,我的假设是;在Java中很难实现,因为该语言不支持任何类似的语言。如果所使用的语言一直都是这样的功能,那么可以理解采取的方法(在定义应该如何工作的规范方面)并且由编译器中的工具支持。

+3

奇怪的是,编译器*已*支持*方法调用*的泛型类型参数的类型推断。但对于*对象实例化*,该功能仅与钻石操作员一起添加。 – 2012-03-01 10:07:23