Reputation: 23105
Processor interface:
public interface Processor<T> {
public void process(T request);
public Class<T> getRequestType();
}
Processor implementation:
public class TextProcessor extends BaseProcessor implements Processor<TextRequest> {
@Override
public void process(TextRequest request) {
// TODO Auto-generated method stub
}
@Override
public Class<TextRequest> getRequestType() {
// TODO Auto-generated method stub
return TextRequest.class;
}
}
Request class:
public class Request {
private long id;
...
}
TextRequest
public class TextRequest extends Request {
String text;
...
}
Main class:
private Map<String, Processor<? extends Request>> processors;
public static void main(String[] args) {
Processor<?> processor = processors.get("proc name");
Request request = objectMapper.readValue(json, processor.getRequestType());
processor.process(request);
}
I am getting compilation error in the process
call.
The method process(capture#10-of ?) in the type Processor<capture#10-of ?> is not applicable
for the arguments (Request)
How can I resolve this issue?
Upvotes: 1
Views: 155
Reputation: 147154
So you've got
Processor<?> processor = ...;
Request request = ...;
processor.process(request);
but process
is declared as
public void process(T request);
Request
cannot be guaranteed to be a subtype of T
, therefore it will not compile.
You need to change Request
to the correct type.
First of all you need need to return the right type of class.
public Class<?> getRequestType();
becomes
public Class<T> getRequestType();
(Edit: This has now been modified in the original question.)
Then we need to read an request object of the correct type. For any particular object ?
here will refer to a particular type. And we can capture that by introducing a new method.
public static void main(String[] args) {
doProcess(processors.get("proc name"));
}
private static <T> void doProcess(Processor<T> processor) {
T request = objectMapper.readValue(json, processor.getRequestType());
processor.process(request);
}
Upvotes: 1
Reputation: 12000
The processor you get in Processor<?> processor = processors.get("proc name");
is parameterized of unknown type which has nothing common with the type in processor.getRequestType()
. It is unclear to me what benefit generics bring to you in this case. It seem you don't have to know what is concrete Request
subtype in main function so everything could be rewritten without generics. The root cause of problem is the processors
map where all processors are in one bunch.
I can imagine benefits of generics for example when the processor map would be implemented as heterogenous map with some correlation between key type and value type. The Processor.getRequestType
would then have to be parametrized by type T
too, then you could use:
public static void main(String[] args) {
Processor<TextRequest> processor = processors.get(TextRequest.class);
TextRequest request = objectMapper.readValue(json, processor.getRequestType());
processor.process(request);
}
Upvotes: 0
Reputation: 135
JAVA generics are checked at compile time.
So when you write Processor<?> processor = processors.get("proc name");
we don't know how to validate request against ?
.
If you can accept this - try with non-generic version of processor:
Processor processor = new TextProcessor();
Otherwise maybe add some constraints for Processor
interface (void process(Request request);
)?
Upvotes: 0