在java库中,我遇到了一个使用泛型返回类型的方法,该类型在参数中没有以任何方式使用:
<T extends ResponseCallBack> T sendData(@Nonnull final OrderIf checkoutOrder, @Nullable final List<NameValueIf> ccParmList) throws Exception;
(ResponseCallBack
是这里的界面)
此签名有何不同之处:
ResponseCallBack sendData(@Nonnull final OrderIf checkoutOrder, @Nullable final List<NameValueIf> ccParmList)
答案 0 :(得分:5)
不同之处在于您可以将此特殊版本用于方法链接。
检查此示例程序:
public class MyFoo {
public <T extends MyFoo> T foo(){
System.out.println("foo");
return (T) this;
}
static class MyBar extends MyFoo{
public <T extends MyBar> T bar(){
System.out.println("bar");
return (T) this;
}
}
public static void main(String[] args) {
final MyFoo foo = new MyFoo().foo();
final MyBar bar1 = new MyBar().foo();
final MyBar bar2 = new MyBar().bar();
}
}
只有<T extends MyFoo>
才能分配bar1变量,没有它,就必须有一个演员:
final MyBar bar1 = (MyBar) new MyBar().foo();
不幸的是,至少在Java 7中,编译器推断在此结束,所以你不能这样做
new MyBar().foo().bar();
答案 1 :(得分:1)
区别在于调用者可以约束在某种程度上返回的类型的第一个参数,而对于第二个参数,您只知道您将获得ResponseCallBack
并且必须执行强制转换如果你想要一个子类型。
例如,您可以做第一个:
Subtype temp = caller.<subtype> sendData(...); // Can also skip explicitly passing the type parameter too
而不是
Subtype temp = (Subtype) caller.sendData(...);
所以我认为这是一种在调用时确保类型安全的方法,同时允许调用者从他/她的代码中消除强制转换。