I'm trying to create a method in a factory class. The return of the subtype must be the same type as the declared argument.
The method declaration worked, but when I try to use, the method is not returning the expected type.
Here is a class exemplifying my problem:
import java.util.HashMap;
/**
*
* @author Marcos Martinewski Alves
*/
public class FooParserFactory {
private static final HashMap<Class<? extends Foo>, FooParser<? extends Foo>> fooParsers = new HashMap();
public static FooParser<? extends Foo> getFooParser(Class<? extends Foo> cls) {
initParsers();
FooParser<? extends Foo> parser = fooParsers.get(cls);
if (parser == null) {
throw new RuntimeException("FooParser not found for class "+cls);
}
return parser;
}
private static void initParsers() {
if (fooParsers.isEmpty()) {
// populate fooParsers hashmap
}
}
}
The foo interface
public interface Foo {
}
The foo implementation
public class FooImpl implements Foo {
}
The FooParser
public interface FooParser<T extends Foo> {
public T parse(Object object);
}
And where the problem occurs
public class FooParserUsage {
public void useFooParser(Object source) {
FooImpl fooImpl = FooParserFactory.getFooParser(FooImpl.class).parse(source); // here
}
}
I'm using NetBeans IDE 8.1 and I'm getting the following error:
incompatible types: CAP#1 cannot be converted to FooImpl where CAP#1 is a frash type-variable CAP#1 extends object from capture of ?
Is there a way to do something like this?
Many thanks in advance
Just because <? extends Foo>
looks the same as <? extends Foo>
doesn't mean they are compatible :-)
You could try to reformulate it as follows:
public static <T extends Foo> FooParser<T> getFooParser(Class<T> cls) {
// ^^^^^^^^^^^^^^^ ^ ^
// introduce a type now these two are "compatible"
// variable
initParsers();
// This line will however require a cast. Judge for yourself if it is safe.
FooParser<T> parser = (FooParser<T>) fooParsers.get(cls);
if (parser == null) {
throw new RuntimeException("FooParser not found for class " + cls);
}
return parser;
}