2013-07-08 9 views
17

代入のジェネリックタイプパラメータは判別できますが、3項演算子(?)のジェネリックタイプパラメータは判別できないのはなぜですか?三項演算子( `?`)を使用するとき、Javaはジェネリック型パラメータを推論できませんか?

は、私が「直接」譲渡の場合にはジェネリック型 パラメータを推定することができることが、三項演算子 (?)の場合に失敗し、コンパイラに関する質問があります。私の例では、GuavaのOptionalクラスを使用して、私の指摘をしていますが、 根本的な問題はOptionalに限定されないと思います。

Optionalは、一般的な機能absent()あります

public static <T> Optional<T> absent(); 

を、私はOptional<Double>Optional<T>を割り当てることができます。

// no compiler error 
final Optional<Double> o1 = Optional.absent(); 

はどのようにコンパイラがTが、この場合にDoubleなければならないこと、わかっていません。三項演算子(?)を使用しているとき、私は特に

ジェネリックパラメータとして Integer私たちに
// Type mismatch: cannot convert from Optional<capture#1-of ? extends Object> to Optional<Integer> 
final Optional<Integer> o2 = true 
    ? Optional.of(42) 
    : Optional.<Integer>absent(); 

コンパイラに指示する必要があり ので、そうでない場合、私は次のようなエラーに

型の不一致を取得:変換できませんfrom Optional<capture#1-of ? extends Object> to Optional<Integer>

なぜ「直接」割り当てと三元 オペレータ?それとも、私が行方不明の何か他のものがありますか?

+0

'of'メソッドの戻り値は何ですか? – sanbhat

+0

'absent()'と同じです: 'public static of(T参照);' –

+0

これをコンパイルするjavacのバージョンは? – Vincent

答えて

9

型推論規則のため、3項式は戻り値の型パラメータを推論しません。三項式の型は、そのオペランドの型に依存する。しかし、オペランドの1つに未定義型パラメータ(Optional.absent())があります。この時点では、三項式はまだ型を持たないため、型パラメータに影響を与えることはできません。

さらに詳しい情報はbug reportを参照してください。あなたはJLSを調べることができます。

条件式のタイプは、LUB(T1、T2)にキャプチャ変換(?? 5.1.10)を適用した結果である

ここJLSは言う:

メソッドの結果が、型Sへの代入変換の対象となるコンテキストで発生した場合、そのメソッドの宣言された結果の型をRとし、R '= R [T1 = B(T1)... Tn = B(Tn)]ここで、B(Ti)は、前のセクションでTiについて推論されたタイプ、またはタイプが推測されなかった場合はTiです。

5

問題は、ternery演算子の結果がo2に割り当てられているということです。 コンパイラは、複数の操作で型を推定できません。

Optional<?> tmp = true ? Optional.of(42): Optional.absent(); 
final Optional<Integer> o2 = tmp; 

二行目の変換は問題です:

は基本的に私はあなたの短縮形を書くと思います。

関連する問題