3項演算子とジェネリクスの戻り値形依存タイプとの相性

組み合わせによってイヤンな場合があるようだ。

    // (1)
    Set<String> hoges1 = Collections.emptySet(); //--> OK

    // (2)
    Set<String> hoges2 = (true) ? Collections.emptySet() : new HashSet<String>(); //-->NG:コンパイルエラー

    // (3)
    Set<String> hoges3;
    if (true) {
        hoges3 = Collections.emptySet(); //-->OK
    } else {
        hoges3 = new HashSet<String>();
    }

    // (4)
    Set<String> hoges4 = (true) ? new HashSet<String>() : new HashSet<String>(); //-->OK

Collections.emptySet()は

    public static final <T> Set<T> emptySet() {
        return (Set<T>) EMPTY_SET;
    }

と実装されている。

この場合、戻り値の変数の型に自動的にフィット(?)するので、(1)のようにキャストエラーが出ることなくシンプルな記法で使用することができる。

これを(2)のように3項演算子の中で使うと、不思議なことに、コンパイルエラーになってしまう。
(3)のようにif文でばらして書くとOKなんだけど。

3項演算子の場合は、戻り値を格納する変数との対応関係がうまくとれないんだろうか。


上記の例だったら、(4)のように明示的にかけば3項演算子でもいいんだけど。