详细解释Java泛型类的以下两个版本之间的区别(如果有的话)?
class C<T>{
T x;
void foo(T y) { … }
}
和
class C<T>{
T x;
<T> void foo(T y) { … }
}
和另一个问题:什么可以写在foo()的主体中,取代导致Java编译器接受C的第一个版本但拒绝C的第二个版本的“......”。
我很困惑。
答案 0 :(得分:10)
class C<T>{
T x;
<T> void foo(T y) { … }
}
是一种令人困惑的写作方式
class C<T>{
T x;
<S> void foo(S y) { … }
}
关于拒绝第二个版本的内容,例如:
class C<T>{
T x;
<T> void foo(T y) { x = y; }
}
会失败,因为如果你将其重写为
class C<T>{
T x;
<S> void foo(S y) { x = y; }
}
你可以立即看到你错过了演员表(确切的编译错误是“不兼容的类型”)。
答案 1 :(得分:2)
在第一个示例中,方法T
中的foo
类型变量表示与类定义C<T>
中声明的类型相同。
第二个例子是一个陷阱,因为方法声明中的T
是一个与类的类型参数无关的完全不同的类型,它碰巧具有相同的名称T
。当局部变量隐藏同名字段时,情况类似。
Eclipse会发出一个很好的编译器警告(如果在设置中打开此警告,不确定它是否默认打开)对于这种情况:
类型参数T隐藏类型T