Java泛型类</t>中void foo(T y)和<t> void foo(T y)之间的区别

时间:2012-05-12 22:12:03

标签: java generics object-oriented-analysis

详细解释Java泛型类的以下两个版本之间的区别(如果有的话)?

class C<T>{
    T x;
    void foo(T y)  { … }
}

class C<T>{
    T x;
    <T> void foo(T y)  { … }
}

和另一个问题:什么可以写在foo()的主体中,取代导致Java编译器接受C的第一个版本但拒绝C的第二个版本的“......”。

我很困惑。

2 个答案:

答案 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