9

これは、ディスカッションに関するフォローアップの質問のようなものです。

Java 7 の addAll() 呼び出し内でダイヤモンド演算子が機能しないのはなぜですか?

Javaチュートリアルから、

http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html

ひし形はメソッド呼び出しで機能することが多いことに注意してください。ただし、より明確にするために、ダイヤモンドを主に使用して、宣言されている変数を初期化することをお勧めします

だから、私は最初の行について少し混乱しています。メソッド呼び出しでダイヤモンドが機能するのはいつですか?

ダイヤモンド演算子の仕組みに関するもう少し詳しい説明は、次の場所にあります。

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20type%20argument%20inference%20for%20constructors ?

そしてこれから、私は次のことを試しましたが、うまくいきます:

私が持っているとします:

private static class Box<T>{
    public Box(T t){}
}
static void f(Box<Integer> box){}

次のような呼び出しは正常にコンパイルされます。

f(new Box<>(new Integer(10)));

上記のメソッド呼び出しでコンストラクターを呼び出す際の型パラメーターは、コンストラクターf()への引数 (つまりInteger) から推測されます。

これは、チュートリアルが言うときの意味ですか

ひし形はメソッド呼び出しで機能することが多いことに注意してください

そうでない場合は、ダイヤモンドがメソッド呼び出しで機能する例を提供してくれる人はいますか?

4

3 に答える 3

3

これは、チュートリアルが言うときの意味ですか

オペレーターに関しては、いくつかの落とし穴がありますが、私はそう思います<>

あなたの場合、コンストラクター引数を使用して型を自明に推測できることを考えると、ボックスのインスタンス化は問題ではありません。or を「取らない」ようにコンストラクターを変更してみて、呼び出しがどのように失敗するIntegerかを確認してください。T

class BadBox<T> {

    private T t;

    public BadBox(){}    

    public void setT(T t) {
        this.t = t;
    }

    static void f(BadBox<Integer> box){}

    public static void main(final String[] args) {
        f(new BadBox<>());  //fails, should have worked ideally
    }    
}

同様に、次のクラスを見てください。

class Testi<R> {    
    public void doIt(Set<? extends R> sets) {
    }

    public static void main(final String[] args) {
            // works since type inference is now possible
        new Testi<CharSequence>().doIt(new HashSet<>(Arrays.asList("a")));

            // fails; nothing which can help with type inference
        new Testi<CharSequence>().doIt(new HashSet<>();
    }       
}

同様に、リンクされた質問の問題 ( に関してaddAll) は、次のようにコンパイラを少し支援することで簡単に解決できます。

List<String> list = new ArrayList<>();
list.add("A");

// works now! use only if you love diamond operator ;)
list.addAll(new ArrayList<>(Arrays.asList(new String[0])));
// or the old-school way
list.addAll(new ArrayList<String>()));

ダイアモンド演算子は、次のように匿名クラスの実装に関しても壊れているようです。

final String[] strings = { "a", "b", "c" };
Arrays.sort(strings, new Comparator<>() {
    @Override
    public int compare(String o1, String o2) {
        return 0;
    }
});

<>幸いなことに、この場合、コンパイラは、匿名クラスでは機能しない/機能しないと明言しています。

于 2011-12-26T17:47:13.867 に答える
1

いつ機能し、いつ機能しないかについて考える価値はないと思います。コンパイラが教えてくれるので、機能していないものを書き直す必要があります。

その背後に本当の理由はありません。開発者が特定の時点での実際のコンパイラの実装の現在の制限を仕様に入れ、それがそうあるべきだと私たちに言ったようです。

Java 8 では、これらの制限の多くが取り除かれ、何もかもが凍りつくことはありません。例えば

Arrays.asList("foo", "bar").addAll(new ArrayList<>());

エラーなしでJava 8でコンパイルされます。そして、なぜですか?

于 2014-02-05T19:05:17.383 に答える
0

それは実際にはメソッド呼び出しに関するものではありません。スタンドアロンのステートメント

new Box<>(new Integer(10));

もコンパイルします。推測するのに十分な情報がありますT(Boxつまり、Integer 引数から)

一方、これはコンパイルされません

new ArrayList<>();

どのようなリストが必要かを知る方法はありません。

Collection<String> strings = new ArrayList<>();

これは、推論がターゲットタイプによって支援されるため機能しますCollection<String>

于 2011-12-26T21:29:01.080 に答える