3

多かれ少なかれ次のような方法があります。ただし、現在、実行時に関数 bla() で返される List を返しList<Bar>ます。

私は両方を作る方法を探しています

List<Interface> =  troubleFuction(foo, bar.getCLass());;

List<Bar> = troubleFuction(foo, bar.getCLass());;

可能。基本的に、インターフェイスと互換性のあるリストを返すようにしたいのですが、これにより次のエラーが発生します

List<capture#3-of ? extends Bar>*タイプの不一致: からに変換できませんList<Interface>*

この戻り値の型を可能にする方法はありますか、または実行時の消去によりこれが不可能になりますか

public <T1 extends Interface, T2 extends Interface> List<"problem"> troubleFunction( T1 in, Class<T2> clazz) {
  return in.doStuffWhichGeneratesAlistOF(clazz)
}

public void bla() {
  Foo foo = new Foo(); // implements interface
  Bar bar = new Bar(); // implements interface
  List<Interface> ifaces = toubleFuction(foo, bar.getCLass());
  List<Bar> mustAlsoWork = toubleFuction(foo, bar.getCLass());
}

編集:既存のコードベースの多くでは、メソッドは次のように呼び出されます

List<Bar> result = troubleFunction(List<Interface> list, Bar.class);

したがって、この戻り値の型は互換性を維持する必要があります (書き換え/リファクタリングはオプションではありません)。

<? super Bar>基本的に、メソッドが次のように呼び出された場合に List を返すようにしたい

troublefunction(foo, Bar.class);

List<? super Foo>呼ばれるとき

troublefunction(foo, Bar.class);
4

4 に答える 4

1

何をする必要があるかを本当に伝えるのに十分な情報を提供していません。たとえば、あなたは私たちに型シグネチャを与えdoStuffWhichGeneratesAlistOF()たり、それが何をするかを教えたりしませんでした。inまた、" " 引数の型がこれらすべてとどのような関係があるのか​​を教えてくれませんでした。

確かに、メソッドの戻り値の型をジェネリックにすることは可能です。例えば、

public <T extends Interface> List<T> troubleFunction(Interface in, Class<? extends T> clazz) {
  List<T> result = new ArrayList<T>();
  result.add(clazz.newInstance());
  return result;
}

そして、次のようにメソッドを直接呼び出すことができ、動作します (型パラメーターは割り当てから推測されるため、明示的に指定する必要はありません)。

List<Interface> iface = this.troubleFunction(foo, bar.getCLass());

しかし、上記のコードで の結果を返す方法を見て、in.doStuffWhichGeneratesAlistOF(clazz)おそらくそのメソッドの戻り値の型もジェネリックにする必要があります。しかし、その方法に関する情報がないため、私はそれについて本当にあなたを助けることはできません.

于 2009-05-26T18:19:11.953 に答える
1

一般に、このような状況では、戻り値に使用される (一般的にパラメーター化された) クラス オブジェクトを明示的に渡す必要があります。

ただし、あなたのケースではすでにこれを行っているように見えるので、troubleFunction返すと宣言するのはうまくいきませんList<T2>か? または、一般的なままにしたい場合は、 return を持っていList<? extends Interface>ます。

于 2009-05-26T14:53:11.277 に答える
0

私はこれをもう一度見ましたが、問題は、私が探していた署名が多かれ少なかれあった「スーパー」戻り値の型を使用したかったということでした:

 public <T1 extends interface, T2 super T1> List<T2> getAList(Class<T1> clazz); 

これは不可能です

于 2009-10-16T10:32:09.183 に答える
0

私が理解しているように、引数の型は、ターゲットの型の前に調べられ、ジェネリック引数を推測します。したがって、ジェネリック引数を明示的に指定する必要があると思います。これは次のようになると思います。

List<Interface> iface = this.<Interface>troubleFunction(foo, bar.getCLass());

どこ

public <T extends Interface> List<T> troubleFunction(
    T in, Class<? extends T> clazz
) {
于 2009-05-26T15:00:00.140 に答える