2011-12-26 7 views
9

これは議論のフォローアップの質問のようなものです:JavaチュートリアルからのJava 7ダイヤモンド操作メソッド呼び出しで

Why doesn't the diamond operator work within a addAll() call in Java 7?

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()のメソッド呼び出しでコンストラクタを呼び出す際の型パラメータは、コンストラクタの引数(つまりInteger)から推測されます。

だから、これはチュートリアルではない、ことができ、誰もが親切にもどこダイヤモンドは作品例を提供する場合はダイヤモンドは、多くの場合、この方法で動作することを

を呼び出す言うとき意味されるものですメソッド呼び出しの

+0

@gurungそのa typo。カット&ペーストの悪い例:( –

答えて

3

だから、これはチュートリアルが

を言うとき、私はそれが<>オペレータに来るとき落とし穴のカップルがありそうだと思うけれども意味されるものです。

あなたのケースでは、コンストラクタ引数を使用して型を簡単に推論できるので、Boxのインスタンス化は問題にはなりません。コンストラクタを「not」に変更して、IntegerまたはTを呼び出し、呼び出しが失敗する方法を参照してください。

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について)あなたのリンク問題の問題は、単に次のようにビットコンパイラを支援することによって解決することができます:同様に

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 
    }  
} 

は、このクラスを見て

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; 
    } 
}); 

幸いなことに、この場合には、コンパイラは<>は/匿名クラスでは動作しませんしないことに言及ではかなり明示的です。

+1

良い答え+1。 –

0

これは、実際にはメソッド呼び出しではありません。スタンドアローンステートメント

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

もコンパイルします。一方(整数引数からすなわち)

BoxためTを推測するのに十分な情報がありますが、これは

new ArrayList<>(); 

リストのようなものが求められているかを知る方法はありませんがコンパイルされません。

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

これは推論は、ターゲット・タイプによってCollection<String>

+1

'new ArrayList <>();'はスタンドアローンのステートメント*として*コンパイルします。 – Holger

1

を助けているので、私はそれが動作しないときはときを考える価値があるとは思わない動作します。コンパイラがあなたに伝えます。したがって、動作していないものを書き直さなければなりません。

本当の理由はありません。開発者が特定の時間に実際のコンパイラの実装の現在の制限を仕様に入れて、それがどうあるべきかを教えてくれるようになっています。

Java 8では、これらの制限が凍結しなくても多くの制限を解除しています。例えば。

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

はエラーなしでコンパイルします。そして、どうしてですか?

関連する問題