Я пытаюсь создать метод в фабричном классе. Возврат подтипа должен быть того же типа, что и объявленный аргумент.
Объявление метода сработало, но когда я пытаюсь использовать, метод не возвращает ожидаемый тип.
Вот пример, иллюстрирующий мою проблему:
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
}
}
}
Интерфейс foo
public interface Foo {
}
Реализация foo
public class FooImpl implements Foo {
}
FooParser
public interface FooParser<T extends Foo> {
public T parse(Object object);
}
И где возникает проблема
public class FooParserUsage {
public void useFooParser(Object source) {
FooImpl fooImpl = FooParserFactory.getFooParser(FooImpl.class).parse(source); // here
}
}
Я использую NetBeans IDE 8.1, и я получаю следующую ошибку:
несовместимые типы: CAP # 1 не может быть преобразован в FooImpl, где CAP # 1 является переменной типа frash CAP # 1 расширяет объект от захвата?
Есть ли способ сделать что-то подобное?
Спасибо заранее
Просто потому что <? extends Foo>
<? extends Foo>
выглядит так же, как <? extends Foo>
<? extends Foo>
не означает, что они совместимы :-)
Вы можете попытаться переформулировать это следующим образом:
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;
}