Have a class implement a generic interface not specified in java

advertisements

I have the following "generic" question

Here is a my generic message interface.

public interface Message<P,R> {
    void setParams(P Params); // and the corresponding getter
    void setResults(R results);
}

For simplicity reasons I would like to specify a number (of interfaces) of messages by predefining the parameter and result type. So that if you work with message X you know what the params and result type are.

Such as

public interface MyMessage extends Message<String,String> {}

That works fine, now I would like to have a common base class which can implement any of the messages.

public class BaseMessage<P,R> implements Message<P,R> {
    P param;
    R results;
    // base implementation
}

The problem of the above now is that I can't have a BaseMessage which implements MyMessage.

Multiple attempts like

public class BaseMessage<T extends BaseMessage<P,R>> implements Message<P,R>

or

public class BaseMessage<? extends BaseMessage<P,R>> implements Message<P,R>

will not work, as the compiler complains that P and R are not bound. Introducing them as additional parameters works again, but at that moment the resulting class will not be cast-able to BaseMessage or the desired MyMessage.

public class BaseMessage<P,R,T extends BaseMessage<P,R>> implements Message<P,R>

I would like to have a generic factory method, which would be given the message class, the parameter and the result object and will return an instance of BaseMessage which implements the MyMessage interface. Like in the follwing

public static <P, R, T extends Message<P,R>> T factory(Class<T> clazz,P p,R r) {
    T a = (T) new BaseMessage<P,R>();
    // create a BaseMessage which which Implements T
    a.setParams(p);
    a.setResults(r);
    return a;
}

Anyone encountered a similar problem, or is that something not possible in Java?

Thanks!


Given the interfaces interface Message<P,R> and interface MyMessage extends Message<String, String> and the class class BaseMessage<P,R> implements Message<P,R>, these are the options I see:

  1. Don't use MyMessage and replace all instances with Message<String, String>. Your factory will be

    public <P,R> Message<P, R> newMessage() {
        return new BaseMessage<P,R>();
    }
    
    
  2. have a class

    class MyBaseMessage extends BaseMessage<String, String> implemens MyMessage
    
    

    The factory will be

    public <M extends Message> M newMessage(Class<M> m) {
        if (m.isAssignableFrom(MyBaseMessage.class)) {
            return (M) new MyBaseMessage();
        }
        if (m.isAssignableFrom(BaseMessage.class)) {
            return (M) new BaseMessage();
        }
        return null;
    }
    
    
  3. Don't use interfaces.

  4. Don't use a factory.

  5. (if everything else breaks) Let your factory be

    public <M extends Message> M newMessage(Class<M> m) {
        try {
            return getImplClass(m).newInstance();
        } catch (Exception ex) { /* do proper error handling */ }
    }
    
    

    getImplClass(): Use javassist to create an implementation class at runtime that implements the interface M and extends BaseMessage.