2011-09-05 22 views
1

作为What are the reasons why Map.get(Object key) is not (fully) generic的后续问题,为什么JDK 6和7接口没有将“get”方法定义为泛型方法,以便编译器可以对返回值使用类型推断?为什么JDK Map.get不支持对返回值的类型推断

例如,如果 “GET” 被定义为:

public <T extends V> T get(Object key) 

然后呼叫者可以这样写:

Map<String,Object> m = new HashMap<>(); 
m.put("key", new Foo()); 
... 
Foo f = m.get("key"); // type inference, implicit cast 

在上面的代码片段,我可以M的定义为Map<String,Foo>,但要注意将m定义为Map<String,Object>而不是Map<String,Foo>在许多情况下很有用,例如,当m可以包含任何类型的值时,但仍可以基于关键字推断值类型,例如一个简单的缓存或上下文对象。

+0

这不就是同一个问题吗?不要回答你回答这个问题的问题吗?如果没有,更具体。 (我最初的反应是简单的投票结束......) –

+0

不,它不一样。 AFAICT,这个问题已经明确地说明了这种差异,但要重申:我不是在问为什么键是Object类型的 - 这在所引用的问题中得到了回答。我在询问如何定义get作为类型的一般方法,这显然是不同的。 – Raman

回答

2

因为不这样做(通常)是安全的。 A Map<String, Object>明确声明其值可以是任何类型的Object,而不仅仅是Foo,因此在典型用法中,不应将其值分配给任何其他值。这样做通常会导致程序员错误,类型系统应该(而且确实)帮助您避免。如果你想做那样的事情,总会有投射,这会使你的意图变得明确。

+0

这也是我的想法。除了投射外,另一种方法是为特定情况创建一个不同的界面,程序员知道这个界面**可以安全地执行此操作。例如,缓存或上下文接口可以使用通用方法签名来避免不必要的转换,但由于Map是更一般的接口,因此不做任何不必要的假设是有意义的。 – Raman

0

在这种特定情况下,编译器会尝试警告您有关不安全的操作,并隐式转换为您需要的任何内容都被认为是不安全的。您需要进行明确的转换以显示开发人员“知道”期望的类型。

Java不支持任何返回类型的类型推断。它确定方法或表达式的返回类型,并且该赋值可能会执行隐式转换。

我看到的唯一例外是在Java 7中添加MethodHandle.invokeExact(),并且由JVM进行特殊处理。它是一项新功能,并不适用于所有情况。 ;)

相关问题