So I'm trying to get a reasonably complicated system working. Here's the basics of what I'm attempting.
Rules:
abstract class Rule
{
// stuff
}
class ExampleRule extends Rule
{
// stuff
}
Handlers:
abstract class RuleHandler<T extends Rule>
{
Class<T> clazz;
RuleHandler(Class<T> forClass)
{
this.clazz = forClass;
}
abstract void doStuff(T rule);
}
class ExampleRuleHandler extends RuleHandler<ExampleRule>
{
ExampleRuleHandler()
{
super(ExampleRule.class);
}
void doStuff(ExampleRule rule)
{
// stuff
}
}
And tying them together:
class HandlerDispatcher
{
Map<Class<? extends Rule>, RuleHandler<? extends Rule>> handlers;
void register(RuleHandler<? extends Rule> handler)
{
handlers.put(handler.clazz, handler);
}
void doStuff(List<Rule> rules)
{
for(Rule rule : rules)
{
RuleHandler<? extends Rule> handler = handlers.get(rule.getClass());
handler.doStuff(rule);
}
}
}
class Test
{
void main()
{
HandlerDispatcher hd = new HandlerDispatcher();
hd.register(new ExampleRuleHandler());
}
}
So far I've attempted various combinations of different parameters (wildcarded, restricted, etc.) and have yet to get this compiling without type-related errors. Any insights, solutions or alternative approaches are welcome.
Observing that
RuleHandler<T extends Rule>
implies RuleHandler<?> === RuleHandler<? extends Rule>
the following code is correct (and compiles)
abstract class RuleHandler<T extends Rule>
{
final Class<T> clazz;
// as before
}
class HandlerDispatcher
{
private final Map<Class<?>, RuleHandler<?>> handlers;
void register(RuleHandler<?> handler)
{
handlers.put(handler.clazz, handler);
}
void doStuff(List<Rule> rules)
{
for(Rule rule : rules)
{
@SuppressWarnings("unchecked")
RuleHandler<Rule> handler = (RuleHandler<Rule>) handlers.get(rule.getClass());
handler.doStuff(rule);
}
}
}
class Test
{
void main()
{
HandlerDispatcher hd = new HandlerDispatcher();
hd.register(new ExampleRuleHandler());
RuleHandler<?> handler = new ExampleRuleHandler();
hd.register(handler);
}
}