5

私はかなり長い間Javaを使用してきましたが、特にジェネリックに関しては、まだはっきりしていないことがあります...

これが問題です:私が使用しているこのSearchクラスがあります(詳細については、こちらを参照してください)。これは次のように構築されています。

public Search(Class<?> searchClass) {...}

さらに、次のように、これをパラメータ化したジェネリック ラッパーがあります。

public class HibernateSearch<E> extends Search implements Serializable {
    public HibernateSearch(Class<E> entityClass) {
        super(entityClass);
    }
    // ... omitted for brevity
}

今、私が必要とするのは次のとおりです。このクラスをフィールドとして含むパラメータ化されたクラスを作成したいと思います。

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {

    private HibernateSearch<T> searchObject;
    ...
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject =
             new HibernateSearchObject<T>( now what...??? );
        ...
    }
    ...
}

私が直面している問題は、与えられた例から明らかだと思います。
誰かがここで何ができるか、またはいくつかの代替案をアドバイスできますか?

4

2 に答える 2

5

最も簡単な方法は、 のインスタンスを実際にインスタンス化して使用する人に責任を転嫁することBaseSelectorComposerです。

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {

    private HibernateSearch<T> searchObject;
    private final Class<T> theType;

    public BaseSelectorComposer(Class<T> token) {
        theType = token;
    }

    ...
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject = new HibernateSearchObject<T>(theType);
        ...
    }
    ...
}

あなたBaseSelectorComposerが抽象サブクラスである場合、これは次のようにのみ使用されます

class IntSelectorComposer extends BaseSelectorComposer<Integer> {
    ...
}

つまり、型パラメーターを「バインド」するクラスの基本クラスとして、リフレクションを介して型情報を取得する方法があります(ただし、これは API IMHO で十分にサポートされていないため、非常に醜いですが)。

于 2013-06-06T13:15:36.477 に答える
1

一般に、これは回避するのが難しいシナリオです。.NET のバックグラウンドから来て、Java は静的なジェネリック型の解決をサポートしていないため (たとえば、.NET で使用できる .NET のように)、これを解決できるケースはほとんどありませんでしtypeof(T)た。

これを回避するには、クラスを外部から取得するか、そのクラスのインスタンスを取得する方法を見つけることをお勧めします。doAfterCompose考えられる解決策は、次のいずれかの方法でメソッドを変更することです。

@Override
public void doAfterCompose(Window comp, Class<?> entityClass) throws Exception {
    super.doAfterCompose(comp);
    this.searchObject =
         new HibernateSearchObject<T>(entityClass);
    ...
}

-また-

@Override
public void doAfterCompose(Window comp, SomeEntity entity) throws Exception {
    super.doAfterCompose(comp);
    this.searchObject =
         new HibernateSearchObject<T>(entity.getClass());
    ...
}

メソッドのシグネチャを変更できない場合 (オーバーライドだと思います)、目的のインスタンス BaseSelectorComposer<T>を保持するクラスのメンバーを使用してみてください。Class<?>

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {
    private Class<?> entityClass;

    public BaseSelectorComposer<T>(Class<?> entityClasss) {
        this.entityClass = entityClass;
    }

   ....
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject =
            new HibernateSearchObject<T>(this.entityClass);
       ...
    }
}
于 2013-06-06T13:15:27.403 に答える