彼らは、異なるインターフェイスとメソッドのための契約を公開制限付きワイルドカードと型パラメータの違いは何ですか?
<N extends Number> Collection<N> getThatCollection(Class<N> type)
と
Collection<? extends Number> getThatCollection(Class<? extends Number>)
彼らは、異なるインターフェイスとメソッドのための契約を公開制限付きワイルドカードと型パラメータの違いは何ですか?
<N extends Number> Collection<N> getThatCollection(Class<N> type)
と
Collection<? extends Number> getThatCollection(Class<? extends Number>)
違いがあります。
最初の宣言では、要素型が引数クラスと同じコレクションを返す必要があります。コンパイラは、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によって利益を無効にする必要があります。
この特定の場合、いいえ。 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)
}
+1。私はあなたがあまりにも遠すぎると思う、最初のものがいつもより良い選択だと思う - 私は「言うまでもなく」より良い選択は文脈に依存すると言うだろう。 –
@スティーブありがとう! 2番目の声明を避ける理由を説明しました。 – notnoop
+1恐ろしい答え! – Stephan