[英]Java generic interface implementation cannot omit type parameter?
我发现在 Java 中我可以使用匿名类来实现像 Runnable(非泛型)这样的接口。 我也可以声明一个变量而不在“=”右侧指定类型参数。 但是我发现对于泛型类型,我不能省略这个:
import java.util.ArrayList;
import java.util.List;
interface Normal {
Integer f();
void g();
}
interface Generic<T> {
T f();
void g();
}
public class GenericInterface {
public static void main(String[] args) {
List<Integer> li = new ArrayList<>(); // ArrayList without type parameter, OK
Runnable r = new Runnable() {
@Override public void run() {}
};
Normal n = new Normal() { // declare implementation, OK.
@Override public Integer f() {
return new Integer(0);
}
@Override public void g() {}
};
Generic<Integer> i = new Generic<>() { // Why need type paramter here?
@Override public Integer f() {
return new Integer(0);
}
@Override public void g() {}
};
}
}
如您所见,javac 报告此行的编译失败:
Generic<Integer> i = new Generic<>() {
虽然编译器足够聪明,可以编译List<Integer> li = new ArrayList<>()
,但当编译器已经知道这条语句左侧的真实类型时,为什么它仍然需要我编写new Generic<Integer>() {
?
还是Java在不指定类型参数的情况下阻止泛型接口实现? 是什么原因?
在 Java 8 中,编译器给出了这个错误:
GenericInterface.java:23: error: cannot infer type arguments for Generic<T>
Generic<Integer> i = new Generic<>() { // Why need type paramter here?
^
reason: cannot use '<>' with anonymous inner classes
where T is a type-variable:
T extends Object declared in interface Generic
1 error
我看不到在 JLS 的 Java 8 版本中明确禁止这样做的地方(但我可能错过了)。
无论如何,这在 Java 9 及更高版本中是允许的。 这是作为Project Coin (JEP 213)的一部分所做的更改之一:
"3. 如果推断类型的参数类型是可表示的,则允许使用匿名类的菱形。因为使用带有匿名类构造函数的菱形的推断类型可能超出签名属性支持的类型集,所以使用带有匿名类的菱形是Java SE 7 中不允许。如 JSR 334 提议的最终草案中所述,如果推断的类型是可表示的,则可以放宽此限制。
这个改进是在 Java 9 中提供的。
是什么原因?
技术原因在上面引用的文本中给出。
因为您有一个方法 f() 需要重载泛型类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.