7

このメソッドは、同じタイプの2つのオブジェクトを受け取り、それらのオブジェクトの1つをランダムに返します。

public static <T> T random(T o1, T o2)
{
   return Math.random() < 0.5 ? o1 : o2;
}

では、なぜコンパイラーは特徴的なタイプの2つのパラメーターを受け入れるのでしょうか。

random("string1", new Integer(10)); // Compiles without errors

編集:両方のパラメーターが暗黙的にアップキャストされていることがわかったので、次のメソッドを呼び出すときに コンパイラー文句を言う のはなぜかと思います。

public static <T> List<T> randomList(List<T> l1, List<T> l2) {
        return Math.random() < 0.5 ? l1 : l2;
    }

電話:

randomList(new ArrayList<String>(), new ArrayList<Integer>()); // Does not Compile

これらのArrayListパラメーターもObjectにアップキャストされている場合、今回エラーが発生するのはなぜですか?

4

4 に答える 4

11

Tはであると推測されObject、両方の引数が暗黙的にアップキャストされています。

したがって、コードは次のようになります。

Main.<Object>random((Object)"string1", (Object)new Integer(10));

さらに驚くべきことは、次のコンパイルが行われることです。

random("string1", 10);

2番目の引数は、に自動ボックス化され、Integerその後、両方の引数がにアップキャストされObjectます。

于 2012-12-18T21:24:45.040 に答える
5

Tとの一般的なスーパータイプであると推測されますStringInteger

Object & Serializable & Comparable<? extends Object & Serializable & Comparable<? extends ... ...

まあ、誰もそれを気にする必要はありません。

パラメータタイプにもう少し制約を追加できます

public static <T1,T2 extends T1> T1 random(T1 o1, T2 o2)

リストの例では、同様の効果を得るにはワイルドカードが必要です

public static <T> List<? extends T> randomList(
                                    List<? extends T> l1, List<? extends T> l2)
于 2012-12-18T21:39:48.160 に答える
3

両方のパラメーターが暗黙的にアップキャストされていることを知っているので、次のメソッドを呼び出すときにコンパイラーが文句を言うのはなぜだろうか。

Aがのサブタイプである場合でも、AとBが異なる場合のサブタイプBList<A>はないためです。List<B>

于 2012-12-19T02:26:21.763 に答える
1

安全で一般的な方法でそれを呼び出さないからです。試す

MyClass.<String>random("string1", new Integer(10));

また、コンパイルエラーが発生します。

または、コンパイラに型を推測させると、コンパイルエラーも発生するはずです。

String s = random("string1", new Integer(10));
于 2012-12-18T21:27:32.527 に答える