In a java library I came across a method which uses a generic return type that is not used in any way in the parameters:

<T extends ResponseCallBack> T sendData(@Nonnull final OrderIf checkoutOrder, @Nullable final List<NameValueIf> ccParmList) throws Exception;

(ResponseCallBack is an interface here)

What is the difference with this signature:

ResponseCallBack sendData(@Nonnull final OrderIf checkoutOrder, @Nullable final List<NameValueIf> ccParmList) 
有帮助吗?

解决方案

The difference is that you can use this special version for method chaining.

Check this sample program:

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();
    }

}

The assignment of the bar1 variable is only possible because of the <T extends MyFoo>, without it, there would have to be a cast:

final MyBar bar1 = (MyBar) new MyBar().foo();

Unfortunately, at least with Java 7, compiler inference ends here, so you can't do

new MyBar().foo().bar();

其他提示

The difference is with the first parameter the caller can constrain the type that is returned to some extent, while for the second you only know that you'll get a ResponseCallBack and will have to perform a cast if you want a subtype.

For example, with the first you can do:

Subtype temp = caller.<subtype> sendData(...); // Can also skip explicitly passing the type parameter too

instead of

Subtype temp = (Subtype) caller.sendData(...);

So I suppose it's a way of ensuring type safety when calling, as well as allowing the caller to eliminate casts from his/her code.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top