说A
是一个界面。有什么区别
public <T extends A> void foo(T t) { ... }
和
public void foo(A a) { ...}
答案 0 :(得分:8)
使用一个对象时没有区别。但想象一下,如果你有
class B extends A { ... }
和
public void f(List<A> list) { ... };
和
public <T extends A> void f(List<T> list) { ... };
使用第一个,您可以传递一个完全类型为List<A>
的列表。使用第二个,您可以传递包含扩展A
的对象的列表。但是,第一个你不能做同样的事情。换句话说,你不能将List<B>
传递给第一个方法,但你可以传递给第二个方法。
答案 1 :(得分:7)
不多。
另一方面,请考虑这种方法:
public <T extends A> T transform(T t);
来电代码:
class B implements A { ... }
B result = transform(new B(...));
如果您将方法声明为
,则不可能(上面不会编译,因为编译器会强制您将result
类型声明为A
)
public A transform(A a)
答案 2 :(得分:4)
您的情况没有区别,因为type参数仅在一个地方使用。两种方法都接受A或扩展A的任何东西。在这种情况下,泛型方法会更有意义,因为type参数允许你将返回值与传递的参数联系起来:
public <T extends A> T f(Class<T>) {...}
答案 3 :(得分:0)
它是否有所作为取决于该功能内部的内容。
仿制药的目的是确保类型安全。假设A有两个子类,我们称之为B和C.在第一个例子中,使用f(List&lt; A&gt;),列表可以包括B,C,或两者的混合。但是在第二个例子中,f&lt; T扩展A&gt;(List&lt; T&gt;),当我们调用该函数时,我们必须指定类型。如果我们说f&lt; B&gt;,那么我们知道这是B的列表,没有C允许。我们不会被允许传递C或通用A的列表,我们不能将任何C添加到列表中,我们取出的任何内容都将被保证为B。
这是好还是坏取决于你想要做什么。如果您想要一个全部为B或全部为C的列表,则通用有助于保证这一点。如果你想要一个可以混合使用的列表,那么你不想使用泛型,使用简单的f(List&lt; A&gt;)。