详细解释以下两个版本的 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 泛型类之间的区别(如果有)?
class C<T>{
T x;
void foo(T y) { … }
}
和
class C<T>{
T x;
<T> void foo(T y) { … }
}
还有另一个问题:在 foo() 的主体中可以写什么,替换将导致 Java 编译器接受 C 的第一个版本但拒绝 C 的第二个版本的“...”。
我很困惑。
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; }
}
您可以立即看到您缺少演员表(确切的编译器错误是“不兼容的类型”)。
在第一个示例中,T
方法中的类型变量foo
表示与类定义中声明的类型完全相同C<T>
。
第二个例子是一个陷阱,因为T
方法声明中的 是完全不同的类型,与类的类型参数无关,只是碰巧同名T
。这与局部变量隐藏同名字段的情况类似。
对于这种情况,Eclipse 会发出一个很好的编译器警告(如果在设置中打开了此警告,则不确定它是否默认打开):
类型参数 T 隐藏了类型 T