以下示例在 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 中所做的影响泛型的更改,但没有与此特定情况匹配的内容。
感谢您的回答。
最佳答案
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/