Java 8 - 向需要泛型类型的方法提供原始类型参数会导致其返回类型被删除

标签 java generics java-8

以下示例在 Java 7 中编译成功,但在 Java 8(及更高版本)中编译失败。

public abstract class Example<T> 
{
    public T method() 
    {
        return method(new HashMap());
    }

    abstract T method(Map<String, String> arg);
}

Java 7:

BUILD SUCCESSFUL in 1s

Java 8:

> Task :compileJava FAILED
C:\dev\projects\Java8\src\main\java\example\Example.java:10: error: incompatible types: Object cannot be converted to T
        return method(new HashMap());
                     ^
  where T is a type-variable:
    T extends Object declared in class Example

上面的错误意味着method(new HashMap())返回Object而不是预期的T .

为了避免 Java 8 中出现此错误,我必须提供泛型类型参数,即更改 new HashMap()new HashMap<>() .

令人不安的部分是由传递给 method(Map<String, String>) 的原始类型参数引起的错误实际上是关于这个方法返回 Object而不是T 。所以我可以预期:

T result = method(new HashMap<>());

...,但是:

Object result = method(new HashMap());

如果在需要泛型类型参数的地方提供了非泛型类型参数,那么突然忘记方法返回的参数化类型似乎不是直观的行为。它只是方法定义中的参数上下文,我希望将其与同一方法定义中的返回类型上下文隔离。

这种行为有正当理由和适用的解释吗?我知道 Java 8 中所做的影响泛型的更改,但没有与此特定情况匹配的内容。

感谢您的回答。

最佳答案

JLS, Chapter 15.

15.12.2.6. Method Result and Throws Types

The result type of the chosen method is determined as follows:

[...] if unchecked conversion was necessary for the method to be applicable, then the result type is the erasure (§4.6) of the method's declared return type. [...]

它是在 JDK-6791481 中提出的.

如果我能成功public abstract class Example<T extends java.lang.Exception> ,那么我会得到error: incompatible types: Exception cannot be converted to T .


(又好像我要一天找不到答案,阐述一个很长的问题,发布它并很快找到答案。)

关于Java 8 - 向需要泛型类型的方法提供原始类型参数会导致其返回类型被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50008656/

相关文章:

java - java发送GCM推送通知的库是什么?

java - Hibernate删除操作不更新MySql

java - 我如何让 Java 为我的类型安全映射文字推断出正确的通用映射类型?

c# - 带有 Id 的通用类 C#

Java 8 lambda API

Java 强制转换异常(不是类强制转换异常)

java - 接口(interface)优于抽象类的情况

java - 无需强制转换即可将值添加到 HashMap

centos - 在 centOs 上使用一种可移植的 JDK

java - Java 8 是否缺少 OptionalBoolean?