[英]Difference between <T extends A> void foo(T t) and void foo(A a)
Say A
is an interface. 说A
是一个界面。 What is the difference between 有什么区别
public <T extends A> void foo(T t) { ... }
and 和
public void foo(A a) { ...}
? ?
There isn't a difference when using one object. 使用一个对象没有区别。 But imagine if you had 但想象一下,如果你有
class B extends A { ... }
and 和
public void f(List<A> list) { ... };
and 和
public <T extends A> void f(List<T> list) { ... };
with the first one you can pass a list that is exactly of type List<A>
. 使用第一个,您可以传递一个完全类型为List<A>
。 With the second one you can pass a list which contains objects that extend A
. 使用第二个,您可以传递包含扩展A
对象的列表。 However, with the first one you cannot do the same thing. 但是,第一个你不能做同样的事情。 So in other words you could not pass List<B>
to the first method but you could to the second method. 换句话说,你不能将List<B>
传递给第一个方法,但你可以传递给第二个方法。
Not much. 不多。
On the other hand, consider this method: 另一方面,请考虑以下方法:
public <T extends A> T transform(T t);
And caller code: 和来电代码:
class B implements A { ... }
B result = transform(new B(...));
It wouldn't be possible (above wouldn't compile, as compiler would force you to declare result
type as A
) had you declared method as 如果您将方法声明为,则不可能(上面不会编译,因为编译器会强制您将result
类型声明为A
)
public A transform(A a)
There is no difference in your case because the type parameter is used in one place only. 您的情况没有区别,因为type参数仅在一个地方使用。 Both methods will accept anything that is an A or extends A. The generic method would make more sense in this case because the type parameter let you tie the return value to the passed parameter: 这两种方法都接受A或扩展A的任何东西。在这种情况下,泛型方法更有意义,因为type参数允许你将返回值与传递的参数联系起来:
public <T extends A> T f(Class<T>) {...}
Whether it makes a difference depends on what's inside that function. 它是否有所作为取决于该功能内部的内容。
The point of generics is to insure type safety. 仿制药的关键是确保类型安全。 Suppose A has two subclasses, let's call them B and C. In the first example, using f(List<A>), the list could include B's, C's, or a mixture of both. 假设A有两个子类,我们称之为B和C.在第一个例子中,使用f(List <A>),列表可以包括B,C或两者的混合。 But in the second example, f<T extends A>(List<T>), when we invoke the function we must specify the type. 但是在第二个例子中,f <T扩展了A>(List <T>),当我们调用该函数时,我们必须指定类型。 If we say f<B>, then we know this is a list of B's, no C's allowed. 如果我们说f <B>,那么我们知道这是一个B的列表,没有C允许。 We will not be allowed to pass in a list of C's or generic A's, we cannot add any C's to the list, and anything we take out will be guaranteed to be a B. 我们不会被允许传入C或通用A的列表,我们不能将任何C添加到列表中,我们取出的任何内容都将保证为B.
Whether this is good or bad depends on what you're trying to do. 这是好还是坏取决于你想要做什么。 If the idea is that you want a list that is either all B or all C, then the generic helps guarantee this. 如果您想要一个全部为B或全部为C的列表,则通用有助于保证这一点。 If you want a list that can be a mix of the two, then you don't want to use the generic, use the simple f(List<A>). 如果你想要一个可以混合使用的列表,那么你不想使用泛型,使用简单的f(List <A>)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.