Java 7的钻石操作符:为什么实现起来很困难?

16

我观看了Oracle OTN虚拟事件:Java SE和JavaFX 2.0(2012年2月28日),在讲解新的钻石操作符(Map<String, List<String>> myMap = new HashMap<>();)时,演讲者提到它并没有想象中那么简单实现,因为它不是一个简单的令牌替换。

我的问题是为什么?为什么不能简单地将变量声明中的字符串放入钻石操作符中呢?


3
点赞。为什么我们需要一个操作符来表示这个动作? - Croo
2个回答

14
我也没有实现它,所以我只能猜测。
但通常情况下,这些事情比看起来更复杂的原因是首次检查只考虑了最常见(或最广为人知)的用例。在这种情况下,就是你提到的那个。理论上应该很容易精确地指定并且在编译器中实现它,这应该相当容易。
然而,钻石操作符(顺便说一下,它不是技术上的运算符)也可以以不同的方式使用:
someMethodWithGenericArguments(new HashMap<>());
new SomeGenericClass(new HashMap<>());
T foo = new SomethingRelatedToT<>(); // where T is a generic type parameter

在这些情况下,简单的令牌替换显然不再适用,您需要实际类型推断涉及实际类型分析(即它处于完全不同的抽象级别,就像简单的令牌替换一样)。

谢谢,我看到这些确实是更复杂的情况。第一个案例引发了一个问题,如果 someMethodWithGenericArguments() 被重载为 Map<String,String>Map<Integer,Integer>,那么钻石操作符对我来说似乎完全不明确。 - jabal
@jabal: 尝试一下吧!由于 Map <String,String>Map <Integer,Integer> 具有相同的擦除(Map),因此您不能将这两个重载放在单个方法中。 - Joachim Sauer

2

Java没有像许多其他语言那样基于使用隐含类型的功能。也就是说,Java不会根据使用方式隐含需要的类型。

例如:

 Type a = b;
ab 的类型是独立的,不会根据 a 的类型对 b 做出任何假设。MethodHandles 正在显示支持此功能。返回类型可以基于上下文进行使用,但这是一个运行时特性。总之,我的假设是:在 Java 中实现这个功能很难,因为该语言不支持类似的功能。如果该语言一直使用这样的功能,那么应该定义如何工作的规范,并由编译器中的工具支持。请注意保留 HTML 标签。

3
有趣的是,编译器已经支持在方法调用中对泛型类型参数进行类型推断。但是,在对象实例化方面,这个特性只是通过钻石操作符才被添加进来的。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接