设A
为接口。
public <T extends A> void foo(T t) { ... }
和
public void foo(A a) { ...}
?
使用一个对象时没有区别。但是想象一下如果你有
class B extends A { ... }
和
public void f(List<A> list) { ... };
和
public <T extends A> void f(List<T> list) { ... };
与第一个,你可以传递一个列表,正是类型List<A>
。对于第二个,你可以传递一个列表,其中包含扩展A
的对象。然而,对于第一个,你不能做同样的事情。换句话说,你不能把List<B>
传递给第一个方法,但是你可以传递给第二个方法。
没什么。
另一方面,考虑这个方法:
public <T extends A> T transform(T t);
和呼叫者代码:
class B implements A { ... }
B result = transform(new B(...));
如果您将方法声明为
,这是不可能的(上面不会编译,因为编译器会强制您将result
类型声明为A
)。public A transform(A a)
在您的情况下没有区别,因为类型参数只在一个地方使用。这两种方法都将接受A或扩展A的任何内容。泛型方法在这种情况下更有意义,因为类型参数允许您将返回值绑定到传递的参数:
public <T extends A> T f(Class<T>) {...}
是否起作用取决于函数内部的内容。
泛型的意义在于确保类型安全。假设A有两个子类,我们称它们为B和C。在第一个例子中,使用f(list ),列表可以包括B、C或两者的混合。但是在第二个示例中,f这是好是坏取决于你想做什么。如果你想要一个全是B或全是C的列表,那么泛型可以帮助保证这一点。如果你想要一个列表,可以是两者的混合,那么你不想使用泛型,使用简单的f(list )。