Я столкнулся с этим сегодня и нашел решение. Спрашивающий, по сути, хочет написать метод, такой как:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Здесь MyInterface - это просто интерфейс маркера для определения диапазона классов, которые я хочу иметь возможность динамически генерировать. Если вы попытаетесь кодировать выше, вы получите ошибку. Хитрость заключается в том, чтобы определить «экземпляр», такой как:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Теперь определите генератор отложенного связывания GWT, который возвращает экземпляр выше. В генераторе запросите TypeOracle, чтобы получить все типы MyInterface и сгенерируйте реализации для них так же, как и для любого другого типа:
например:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
Класс MyIntefaceGenerator, как и любой другой генератор отложенных привязок. За исключением того, что вы вызываете его непосредственно в вышеупомянутом генераторе, а не через GWT.create. Когда генерация всех известных подтипов MyInterface завершена (при генерации подтипов MyInterface в генераторе убедитесь, что имя класса имеет уникальный шаблон, такой как MyInterface.class.getName () + "_MySpecialImpl") просто создайте Instantiator, повторив все известные подтипы MyInterface и создав группу
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
стиль кода. Наконец, выведите исключение, чтобы вы могли возвращать значение во всех случаях.
Теперь, когда вы бы позвонили GWT.create(clz);
, вместо этого сделайте следующее:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Также обратите внимание, что в вашем XML-модуле GWT вы будете определять генератор только для Instantiator, а не для генераторов MyInterface:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Бинго!