为什么JDK Map.get不支持返回值的类型推断

时间:2011-09-05 02:30:40

标签: java generics casting type-inference

作为What are the reasons why Map.get(Object key) is not (fully) generic的后续问题,为什么JDK 6和7 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可以包含任何类型的值,但仍可以根据键推断值类型,例如一个简单的缓存或上下文对象。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

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