私は今日これに遭遇し、解決策を見つけました。質問者は基本的に、次のようなメソッドを書きたいと考えています。
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.
}
MyInterfaceGenerator クラスは、他の遅延バインディング ジェネレーターと同じです。GWT.create 経由ではなく、上記のジェネレーター内で直接呼び出すことを除いて。MyInterface のすべての既知のサブタイプの生成が完了したら (ジェネレーターで MyInterface のサブタイプを生成するときは、クラス名が MyInterface.class.getName() + "_MySpecialImpl" などの一意のパターンを持つようにしてください)。 、 MyInterface のすべての既知のサブタイプを再度繰り返し、一連のサブタイプを作成することにより、単純に Instantiator を作成します
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);
また、GWT モジュール xml では、MyInterface ジェネレーターではなく、Instantiator のジェネレーターのみを定義することに注意してください。
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
ビンゴ!