i want to dispatch messages to specific handlers through a common message processor
//
// Library code
//
abstract class Processor<M extends MessageHandler<? extends Message>> {
HashMap<Class<Message>, M> handlerMap;
void addHandler(M, Class<Message>);
void run() {
while(true) {
...
}
}
// QUESTION - how to define this to include the fact that H extends M<T>
// actually im just trying to avoid the ugly cast in the client code.
abstract <H extends MessageHandler<T>, T extends Message> void dispatch(H handler, T message);
}
class MessageHandler<T extends Message> {
}
class Message {
}
//
// Client code
//
class ServerMessage extends Message {
...
}
class ServerMessageHandler<T extends Message> extends MessageHandler<T> {
...
void process(T msg, Object... params) {
...
}
}
class ServerProcessor extends Processor<ServerMessageHandler<? extends Message>> {
@Override
<H extends MessageHandler<T>, T extends Message> void dispatch(H handler, T message) {
// QUESTION - how do i get rid of this cast?
((ServerMessageHandler<T>)handler).process(T, ...);
}
}
the server processor will be processing many different server messages, all with their own subtypes, members, etc. each one of these messages will have a separate handler. some base message classes will share handlers.
my question is how do i avoid that ugly cast in the client code? i cant seem to write the signature of the dispatch method to include the facts that we know the message handlers will be of type M (ServerMessageHandler), and that the particular ServerMessageHandler is parameterized by T, and a message of type T will be in the arguement list.
EDIT
i dont mind if the addHandler method cannot get total type safety, i can do some runtime checks to make sure the proper relationships are enforced ( i would have to change its signature to do that properly though ). my main goal here is to somehow enforce (through the signature) the two relationships in the dispatch method. that the handler being called is of type M, and that it is parameterized by T. to actually call this method there will be some unchecked casts in the run method (which in turn calls dispatch). but i dont mind having the ugliness there. just trying to move it out of the ServerProcessor.