You have a wildcard in the type parameter of your handler variable. The compiler does not know what the exact type of this parameter is, only that it is either Monitor or a subclass.
The call method takes a T that maps to a wildcard. But there is no guarantee that the type of the wildcard is ContainsMonitor . It could be Monitor , or it could be MonitorSubtypeThatDoesntExistYet . Since the compiler does not know the actual type, it cannot skip anything but null , because with any argument not null it cannot guarantee type safety.
You can get around this by removing the wildcard and replacing the concept with a type parameter in the Monitor class.
class Monitor<T extends Monitor<T>> { WebScoutCallable<T> handler; public void setCallable(WebScoutCallable<T> callable) { this.handler = callable; } }
The WebScoutCallable interface WebScoutCallable slightly in response:
interface WebScoutCallable<T extends Monitor<T>> { public void call(T caller); }
A subclass substitutes its name as a type argument when extending Monitor .
class ContainsMonitor extends Monitor<ContainsMonitor> { public void handleDocument() { handler.call(this); } }
Now T will be a known type, and ContainsMonitor defines it as itself, so now it is legal to go to call .
rgettman
source share