0

質問のタイトルはかなりぎこちなく感じます。編集お疲れ様です。割り当てられた によって指定された特定の種類のオブジェクトの
を返す再利用可能なクエリを作成しようとしています。 これはうまくいきませんが、私がやろうとしていることを明らかにすると思います:ListString

public List<?> getAll(String type) {
    Class clazz = Class.forName(type);
    return (List<clazz>) em.createQuery("SELECT t from " + type + " t").getResultList();
}
4

1 に答える 1

5

タイプのクラスを使用してみてください:

public <T> List<T> getAll(Class<T> type) {
  return em.createQuery("SELECT t from " + type.getSimpleName() + " t").getResultList();
}

getResultList()生のリストを返すため、これでも警告が生成されることに注意してください。

編集

完全修飾クラス名しかない場合、つまり を呼び出す必要がある場合Class.forName()、コンパイル時にクラスを知る方法はありません。また、ジェネリックは (ほとんど) コンパイル時の機能のみであるため (ヒント: 型消去)、役に立ちません。その場合。

Class.forName()次のように取得したクラスでジェネリック メソッドを呼び出すこともできます。

List<?> l = getAll( Class.forName( typeName ));

クエリのためだけの場合は、クラス オブジェクト自体を取得する必要がない場合もあります (ただし、文字列が既存のクラスの名前であることを最初に確認することは理にかなっている場合があります)。この場合、メソッドは次のようになります。

public List<?> getAll(String type) {
   return em.createQuery("SELECT t from " + type + " t").getResultList();
}

このバリアントでは、完全修飾クラス名またはエンティティ名のいずれかを渡すこともできます。つまり、多少柔軟になります。

または、を返すこともできList<Object>ます。これにより、さらにオブジェクトをリストに追加できます (ただし、何でも追加できることに注意してください)。

そうは言っても、私は可能な限り最初のオプションを使用し、2 番目のオプションはコンパイル時に具体的な型 (または少なくとも一部のインターフェイス) が不明な場合のフォールバックとして使用します。

于 2013-10-23T08:17:40.167 に答える