I am getting the below error:
'call(ContainsMonitor)' cannot invoke 'call(? extends webscout.Monitor)' in 'WebScoutCallable'
Monitor.java
WebScoutCallable<? extends Monitor> handler;
public setCallable(WebScoutCallable<? extends Monitor> callable) {
this.handler = callable;
}
WebScoutCallable.java
public interface WebScoutCallable<T extends Monitor> {
public void call(T caller);
}
ContainsMonitor.java
public class ContainsMonitor extends Monitor {
public void handleDocument() {
handler.call(this);
}
}
I'll freely admit that I'm new to generics and still quite new to Java itself. I find the error message confusing as it looks like it should work (method declaration expects a Monitor or subclass, I'm passing in a subclass). Any help (+explanation) would be greatly appreciated!
Thanks!
You have a wildcard in the type parameter of your
handlervariable. The compiler doesn't know what the exact type of this type parameter is, only that it's eitherMonitoror a subclass.The
callmethod takes aT, which is matched on the wildcard. But there is no guarantee that the wildcard type is aContainsMonitor. It could be aMonitor, or it could beMonitorSubtypeThatDoesntExistYet. Because the compiler doesn't know the actual type, it cannot allow you to pass anything exceptnull, because with any non-nullargument, it can't guarantee type safety.You can get around this by removing the wildcard, and replacing that concept with a type parameter on the
Monitorclass.The interface
WebScoutCallablechanges a little in response:The subclass feeds its own name as the type argument when extending
Monitor.Now,
Twill be a known type, andContainsMonitordefines it to be itself, so it's now legal for it to pass itself tocall.