I have a complex generic type implementation in Java but I could not complete it. I am getting error on AddItemEvent class. The return type in the getHandler does not match with it's parent class requires.
AddItemEventHandler is actually a BaseEventHandler<BaseEvent<AddItemCommand, AddItemPayload>, AddItemCommand, AddItemPayload> but I get an error on that line.
public abstract class BasePayload {
}
public class AddItemPayload extends BasePayload {
private int id;
private String name;
public AddItemPayload(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
public class BaseCommand<T extends BasePayload> {
String command;
T payload;
public BaseCommand(String command, T payload) {
this.command = command;
this.payload = payload;
}
}
public class AddItemCommand extends BaseCommand<AddItemPayload> {
public AddItemCommand(AddItemPayload payload) {
super("AddItem", payload);
}
}
public abstract class BaseEventHandler<E extends BaseEvent<C, P>, C extends BaseCommand<P>, P extends BasePayload> {
abstract public void onTry(E event, ArrayList<BaseEvent<?, ?>> actualEvents);
abstract public void onCommit(String uuid, E event);
}
public class AddItemEventHandler extends BaseEventHandler<AddItemEvent, AddItemCommand, AddItemPayload> {
@Override
public void onTry(AddItemEvent event, ArrayList<BaseEvent<?, ?>> actualEvents) {
}
@Override
public void onCommit(String uuid, AddItemEvent event) {
}
}
public abstract class BaseEvent<C extends BaseCommand<P>, P extends BasePayload> {
abstract protected BaseEventHandler<BaseEvent<C, P>, C, P> getHandler();
}
public class AddItemEvent extends BaseEvent<AddItemCommand, AddItemPayload> {
@Override
protected BaseEventHandler<BaseEvent<AddItemCommand, AddItemPayload>, AddItemCommand, AddItemPayload> getHandler() {
return new AddItemEventHandler(); // I have an error on this line
/*
Incompatible types. Found: 'org.example.handlers.AddItemEventHandler',
required: 'org.example.handlers.BaseEventHandler<org.example.events.BaseEvent<org.example.commands.AddItemCommand,org.example.payload.AddItemPayload>,
org.example.commands.AddItemCommand,org.example.payload.AddItemPayload>'
*/
}
}
You cannot assign a variable of type List<AddItemEvent> to a reference of type List<BaseEvent<AddItemCommand, AddItemPayload>>. That's because the latter allows more - it allows not just AddItemEvent instances, but any instance that extends BaseEvent<AddItemCommand, AddItemPayload>.
Your compiler error has the same cause. The handler would allow more than only AddItemEvent instances.
One solution can be to add an extra generic type to BaseEvent for the event itself:
public abstract class BaseEvent<E extends BaseEvent<E, C, P>, C extends BaseCommand<P>, P extends BasePayload> {
abstract protected BaseEventHandler<E, C, P> getHandler();
}
That has to be propagated to some of the other types:
public abstract class BaseEventHandler<E extends BaseEvent<E, C, P>, C extends BaseCommand<P>, P extends BasePayload> {
// additional ? in BaseEvent
abstract public void onTry(E event, ArrayList<BaseEvent<?, ?, ?>> actualEvents);
abstract public void onCommit(String uuid, E event);
}
public class AddItemEventHandler extends BaseEventHandler<AddItemEvent, AddItemCommand, AddItemPayload> {
@Override
// additional ? in BaseEvent
public void onTry(AddItemEvent event, ArrayList<BaseEvent<?, ?, ?>> actualEvents) {
}
@Override
public void onCommit(String uuid, AddItemEvent event) {
}
}
// additional generic type: AddItemEvent
public class AddItemEvent extends BaseEvent<AddItemEvent, AddItemCommand, AddItemPayload> {
@Override
// replace BaseEvent<AddItemCommand, AddItemPayload> with AddItemEvent
protected BaseEventHandler<AddItemEvent, AddItemCommand, AddItemPayload> getHandler() {
return new AddItemEventHandler(); // no more error
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With