【问题标题】:Difference between void foo(T y) and <T> void foo(T y) in Java generic classJava泛型类中void foo(T y)和<T> void foo(T y)的区别
【发布时间】:2012-05-12 22:12:03
【问题描述】:
详细解释以下两个版本的 Java 泛型类之间的区别(如果有)?
class C<T>{
T x;
void foo(T y) { … }
}
和
class C<T>{
T x;
<T> void foo(T y) { … }
}
还有另一个问题:在 foo() 的主体中可以写什么,替换“...”会导致 Java 编译器接受 C 的第一个版本但拒绝 C 的第二个版本。
我很困惑。
【问题讨论】:
标签:
java
generics
object-oriented-analysis
【解决方案1】:
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; }
}
您可以立即看到您缺少强制转换(确切的编译器错误是“不兼容的类型”)。
【解决方案2】:
在第一个示例中,方法foo 中的T 类型变量表示的类型与在类定义C<T> 中声明的类型完全相同。
第二个例子是个坑,因为方法声明中的T是完全不同的类型,与类的类型参数无关,恰好同名T。类似于局部变量隐藏同名字段的情况。
对于这种情况,Eclipse 会发出一个不错的编译器警告(如果在设置中打开了此警告,则不确定它是否默认打开):
类型参数T隐藏了类型T