2

次のことを行うための適切なパターンを探しています。クラスがあり、単一のパラメーターを持つコンストラクターがあるFooBar<A,B>ことを知っています。次の署名を使用して保護されたメソッドを作成したいと思います。ABFooBar

protected A chuckNorris42(B b); // intent: return new A(b)

もちろん、上記の「意図」はコンパイルできません。回避策として、このメソッドを抽象化FooBarし、具象クラスでインスタンス化する時点でchuckNorris42インラインで実装しました。

FooBar<Chuck, Norris> = new FooBar<Chuck, Norris>() {
  protected Chuck chuckNorris42(Norris norris) {
    return new Chuck(norris);  
  }
}

それは機能しますが、同じことを達成するためのより良い方法やよりクリーンな方法があるかどうか疑問に思ったので、ここで質問することにしました.

4

3 に答える 3

4

重要なのは、Aの実際のインスタンスにそのようなコンストラクターがあることを知らないということです。Java型システムは、これを強制するのに十分なほど強力ではありません。したがって、静的にわからないクラスのコンストラクターを呼び出すためのクリーンで汎用的な組み込みの方法はありません。他の回答と同様にリフレクションを使用する必要がありますが、インスタンス化できない型(たとえば、Aは抽象クラスである可能性があります)でAが突然インスタンス化された場合、またはAがない場合、これは実行時に失敗する可能性があります。適切なコンストラクタ。これを避けたい場合は、ファクトリを使用できます。

interface Factory<A, B> {
  A createInstance(B b);
}

次に、クラスのユーザーに、FooBarタイプAおよびBの現在の値のファクトリのインスタンスを提供させます。

于 2012-04-05T10:00:18.883 に答える
2

どれだけきれいできれいかはわかりませんが、次のようなことを試すことができます:

public class FooBar<A,B> {
private Class<A> aClass;
public FooBar(Class<A> aClass) {
    this.aClass = aClass;
}

protected A chuckNorris42(B b) throws NoSuchMethodException, InstantiationException,IllegalAccessException,InvocationTargetException{
    return aClass.getConstructor(b.getClass()).newInstance(b);
}
}

ジェネリック引数のクラスを取得する方法はありません。したがって、ジェネリック引数クラスのオブジェクトをインスタンス化する方法の 1 つは、クラスをコンストラクターに渡すことです。

更新:ジェネリック引数を階層の下に分割 する方法もあります。

public abstract class Foobar<A,B> {
   protected abstract A chuckNorris(B b);
}

public class FooBarChuck<B> extends Foobar<Chuck<B>,B>{

   @Override
  protected Chuck<B> chuckNorris(B b) {
      return new Chuck<B>(b);
  }
}
public class Chuck<B> {
  public Chuck(B b) {
    //something here
  }
}

次に、すべての B クラスに対してこのメ​​ソッドを再実装する必要はありませんが、Chuck ごとに個別のクラスを作成する必要があります。

PS私は実際、この方法があなたのものよりもずっときれいだとは思いません:)

于 2012-04-05T08:30:00.753 に答える
0

次のようなリフレクションを試すことができます

public A produce(Class<A> clazz, B arg) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    return clazz.getConstructor(arg.getClass()).newInstance(arg);
}
于 2012-04-05T08:24:36.503 に答える