简体   繁体   中英

How to create generic methods that take any type parameter?

I have an abstract superservice that should perform some common logic. Several services implement this superservice. I chose the ServiceImpl based on a condition, and want to assign it to the abstract type, for later running the common logic.

What is wrong with the following? I'd like to pass into the process() method any object that is of / extends BaseResponse , like FirstResponse in my example.

//superservice
abstract class AbstractService<T extends BaseResponse> {
    public void process(T t) {
        //execute logic that is common to a BaseResponse
    }
}

//implementations
class FirstService extends AbstractService<FirstResponse extends BaseResponse> {
}

//usage
AbstractService<? extends BaseResponse> myservice = new FirstService(); //chose by condition
myservice.process(new FirstResponse()); //ERROR

result:

    The method build(capture#2-of ? extends BaseResponse) 
in the type AbstractService<capture#2-of ? extends BaseResponse> is not applicable for the arguments (FirstResponse)
    //execute logic that is common to a BaseResponse

If that's the case, the flexibility provided by inheritance is enough, you don't really need generics.

public void process(BaseResponse t) {
    // ...
}

The reason of error is that, the Java compiler only knows myservice is an AbstractService<? extends BaseResponse> AbstractService<? extends BaseResponse> . It is not wrong to reassign myservice to a different subclass later:

AbstractService<? extends BaseResponse> myservice = new FirstService();
myservice = new SecondService(); // <---------- should be ok
myservice.process(new FirstResponse()); // <--- making this bad

would probably be a true error. If you need to keep the interface of process(T) , you have to change the type of myservice then:

FirstService myservice = new FirstService();
myservice.process(new FirstResponse());

You could do it with generics like this:

abstract class AbstractService<T extends BaseResponse> {
    public void process(T t) {
        //execute logic that is common to a BaseResponse
    }
}

//implementations
class FirstService extends AbstractService<FirstResponse> {
    @Override
    public void process(FirstResponse firstResponse) {
        super.process(firstResponse);
        ...
    }
}

public static void main(String[] args) {
    //usage
    AbstractService<FirstResponse> myservice = new FirstService(); 
    myservice.process(new FirstResponse()); 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM