我有一个带有类型参数的类。
class MyObject<IdType> {
@Setter
@Getter
private IdType id;
}
我想我可以添加一些便利的方法,所以我做到了。
<T extends MyObject<? super IdType>> void copyIdTo(T object) {
object.setId(getId());
}
< T extends MyObject<? extends IdType>> void copyIdFrom(T object) {
object.copyIdTo(this);
}
我只是意识到我可以做到。
void copyIdTo(MyObject<? super IdType> object) {
object.setId(getId());
}
void copyIdFrom(MyObject<? extends IdType> object) {
object.copyIdTo(this);
}
这两组方法是否等效?哪种方式(或样式(更喜欢?
在您的情况下,这两种方法实际上是等效的。他们都将参数类型限制为MyObject<...>
或子类型。
由于您的示例方法返回void
,因此制作方法通用并没有真正的好处。对于您的方法而言,唯一重要的是,该参数是MyObject<...>
,即实际类型是毫无意义的。添加使参数类型更具体的功能可以为该方法的实现添加什么都没添加,并且对呼叫者无能为力。换句话说,这是无关紧要的"绒毛"。
因此,对于您的示例,我想说的是非生成选项。它更干净,更简单。
但是,如果您的方法将给定的参数返回给呼叫者,则使该方法通用可能有用;它将允许您将返回类型声明为T
。这为呼叫者打开了可能性,例如方法链接或调用方法"内部"另一种方法调用,所有这些都基于传递的特定类型作为参数。核心库中的一个示例是Objects.requireNonNull(T)
。
@thilo在评论中提到了制作该方法通用的另一个好案例:
另一种情况是,如果您的方法采用多个参数。然后,您可以引入
T
来确保这两个参数具有相同的类型(而不是[分别满足]约束的两种不同类型(。
是的,它们是等效的。两组方法都声明了同一件事 - 方法参数必须是类型MyObject<>
或兼容亚型(子类(。
以这种方式声明T
的唯一原因是,如果您需要在其他地方参考T
,例如该方法的返回类型,或者如果您具有相同类型的多个参数,或者在方法主体内部。
我总是更喜欢较短,更简单,更清晰的版本,而角度较小,而不是伤害眼球:(