user489041
user489041

Reputation: 28304

Java Generics: Require generic to be subclass of a certain type

I have an abstract generic class:

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler>
{
    public abstract List<String> getTypesOfMessages();
    public abstract void handleMessage(String message, CometClient client);

    public T setResponseValues(AbstractMessage request, T response )
    {
        response.setCompanyId(request.getCompanyId());
        response.setMessageGroup(request.getMessageGroup());
        response.setUserId(request.getUserId());
        response.setTimeStamp(AbstractMessage.getCurrentTimeStamp());

        return response;
    }
}

I need the generic subclass to be a subclass of this class. In otherwords, the generic must be a subclass of AbstractMessageHandler. This however gives me compilation issues. Can anyone let me know what I am doing wrong?

Thanks

Upvotes: 7

Views: 4055

Answers (3)

newacct
newacct

Reputation: 122449

From the code given, it doesn't seem like there's any need to make the class generic. How about a generic method instead (I've even made it static, as it doesn't seem that you need to use the current object at all):

public abstract class AbstractMessageHandler
{
    public static <T extends AbstractMessageHandler> T setResponseValues(AbstractMessage request, T response )
    {
        response.setCompanyId(request.getCompanyId());
        response.setMessageGroup(request.getMessageGroup());
        response.setUserId(request.getUserId());
        response.setTimeStamp(AbstractMessage.getCurrentTimeStamp());

        return response;
    }
}

Or even better, just define a method on AbstractMessageHandler that operates on the current object. Then you don't need this static method, and you don't have this weird parameter that you always return.

public abstract class AbstractMessageHandler
{
    public void setResponseValues(AbstractMessage request)
    {
        setCompanyId(request.getCompanyId());
        setMessageGroup(request.getMessageGroup());
        setUserId(request.getUserId());
        setTimeStamp(AbstractMessage.getCurrentTimeStamp());
    }
}

Upvotes: 0

jtahlborn
jtahlborn

Reputation: 53694

You need to follow the example of the Enum class:

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler<T>>

Upvotes: 8

Reverend Gonzo
Reverend Gonzo

Reputation: 40821

In your generic definition you can do <T extends SomeClass>

For example:

abstract class Processor<T extends String> {
    abstract T process();
}

In your case, it looks like T should extend some Response class, and not AbstractMessageHandler.

Upvotes: 0

Related Questions