2009-11-17 7 views

答えて

34

違いがあります。

最初の宣言では、要素型が引数クラスと同じコレクションを返す必要があります。コンパイラは、Nの型を推論します(指定されていない場合)。最初の宣言を使用したときに次の2つのステートメントが有効です。

Collection<Integer> c1 = getThatCollection(Integer.class); 
Collection<Double> c2 = getThatCollection(Double.class); 

2番目の宣言は、引数のクラスに返されたコレクションの型引数との関係を宣言していません。確かに関係がある場合

// Invalid statements 
Collection<Integer> c1 = getThatCollection(Integer.class); // invalid 
Collection<Double> c2 = getThatCollection(Double.class); // invalid 
Collection<Number> cN = getThatCollection(Number.class); // invalid 

// Valid statements 
Collection<? extends Number> c3 = getThatCollection(Integer.class); // valid 
Collection<? extends Number> c4 = getThatCollection(Double.class); // valid 
Collection<? extends Number> cNC = getThatCollection(Number.class); // valid 

勧告

:クライアントは関係なく、引数が何であるかの、Collection<? extends Number>として返さ型を使用しなければならないので、コンパイラは、彼らは無関係であると仮定しています返される型引数と渡された引数の間に型を指定すると、最初の宣言を使用する方がはるかに優れています。上記のように、クライアントコードはよりクリーンです。

関係が存在しない場合は、2番目の宣言を避ける方が良いです。バインドされたワイルドカードを使用して返される型を持つと、クライアントはワイルドカードをどこからでも使用できるようになり、クライアントコードが混乱し、読み取れなくなります。ジョシュア・ブロッホは、Avoid Bounded Wildcards in Return Types(スライド23)でなければならないと強調しています。戻り値の型にある有界のワイルドカードは便利な場合もありますが、結果コードの醜さは、IMHOによって利益を無効にする必要があります。

+3

+1。私はあなたがあまりにも遠すぎると思う、最初のものがいつもより良い選択だと思う - 私は「言うまでもなく」より良い選択は文脈に依存すると言うだろう。 –

+0

@スティーブありがとう! 2番目の声明を避ける理由を説明しました。 – notnoop

+0

+1恐ろしい答え! – Stephan

-3

この特定の場合、いいえ。 2つ目のオプションは、collectionパラメータに含まれる型よりも異なる型の要素を含むコレクションを返すことができるため、柔軟性があります。

具体例:違いの明確な説明のための

Collection<? extends Number> getRoot(Class<? extends Number> number){ 
    ArrayList<Integer> result=new ArrayList<Integer>(); 
    result.add(java.util.Math.round(number); 
    return result) 
} 
関連する問題