異なるタイプの T と S の 2 つの List を取り、両方の要素を含む 1 つの List を返す "mix" メソッドがあるとします。型の安全性のために、返される List が R 型であることを指定したいと思います。ここで、R は T と S の両方に共通のスーパータイプです。たとえば、次のようになります。
List<Number> foo = mix(
Arrays.asList<Integer>(1, 2, 3),
Arrays.asList<Double>(1.0, 2.0, 3.0)
);
これを指定するには、メソッドを次のように宣言します。
static <R, T extends R, S extends R> List<R> mix(List<T> ts, List<S> ss)
mix
しかし、クラスで static ではなくインスタンス メソッドを作成したい場合はどうすればよいList2<T>
でしょうか。
<R, T extends R, S extends R> List<R> mix ...
<T>
のインスタンスで をシャドウするList2
ので、それは良くありません。
<R, T extends S&T, S extends R> List<R> mix ...
シャドーイングの問題を解決しますが、コンパイラには受け入れられません
<R super T, S extends R> List<R> mix ...
下限のワイルドカードは名前付き変数に格納できないため、コンパイラによって拒否されます (? super X
式でのみ使用されます) 。
のように、引数をクラス自体に移動することもできますList2<R, T extends R, S extends R>
が、型情報は実際にはインスタンス レベルにあるわけではありません。これは、1 つのメソッド呼び出しにしか使用されず、必要なたびにオブジェクトを再キャストする必要があるためです。異なる引数でメソッドを呼び出します。
私が知る限り、ジェネリックでこれを行う方法はありません。私ができる最善List2
の方法は、ジェネリックが導入される前のように、生を返し、呼び出しサイトでキャストすることです。誰かがより良い解決策を持っていますか?