Java APIでタイプ弁別子よりワイルドカードを好む理由(Re:Effective Java)


8

Blochの効果的なJavaのジェネリックセクション(誰でも簡単に利用できる「無料」の章:http : //java.sun.com/docs/books/effective/generics.pdf)で、彼は次のように述べています。

型パラメーターがメソッド宣言に1回だけ出現する場合は、ワイルドカードに置き換えます。

(そのPDFの31-33ページを参照してください)

問題の署名は次のとおりです。

public static void swap(List<?> list, int i, int j)

public static void swap(List<E> list, int i, int j)

次に、実際の型パラメーターを指定した静的なプライベート「ヘルパー」関数を使用して作業を実行します。ヘルパー関数のシグネチャは、2番目のオプションのシグネチャとまったく同じです。

とにかくワイルドカードを使用して作業を完了する必要がないので、なぜワイルドカードが望ましいのですか?この場合、彼はリストを変更していて、無制限のワイルドカードを使用してコレクションに追加できないので、なぜそれを使用するのですか?

回答:


5

ワイルドカードが望ましい理由

ジョシュはそれを明確に述べていると思います:

パブリックAPIでは、[ワイルドカード]の方がシンプルであるため、優れています。

つまり、APIのユーザー向けです。実装の小さな余分な複雑さは、外部からは見えません。また、実装は1回しか記述されていませんが、APIは多くの異なる人々によって何度も使用される可能性があるため、実装をわずかに複雑にするという犠牲を払ってAPIを単純化することは、依然として全体的な勝利です。

>なぜそれを使用するのですか?

つまり、なぜそれが

public static void swap(List list, int i, int j)

?後者はジェネリックを完全に失うので、コンパイラーにすべてのジェネリック型チェックを省略させ、ずさんなコードを書けるようにします。ジェネリック型シグネチャは、一般的なものであっても、習慣を守るために使用する方が良いと思います。

以下のコメントを反映して更新

2番目の署名からのジェネリックパラメーター宣言を忘れた、正しく

public static <E> void swap(List<E> list, int i, int j)

つまり、<E>追加のメリットがないため<?>、最初の署名で1回だけ表示されるのに対し、2回表示されます。これがより簡単な理由です。


1
いいえ、なぜswap(List <E>、...)よりもswap(List <?>、...)が望ましいのでしょうか。どのような状況においても、なぜそれがより単純であるのかはわかりません。
マイケルキャンベル、

1
本当にメリットを見ないでください。ユーザーがswapメソッドを使用するには、バージョンpublic static <E> void swap(List <E> list、int i、int j)またはpublic static void swap(List <?> list、int i、int j)まったく同じ、つまりswap(myList、0、1)です。したがって、<E>が2回出現するか、ワイルドカードを使用するかは、私の意見では実際には問題ではありません。多分私は何かが足りないのですか?
ウィル

1
@呼び出し前に、(通常は)API宣言を読み取ります。宣言のワイルドカードバージョンは、脳の解釈が(わずかに)簡単です。
ペーテルTörök

1
わかりました、それは本当にこの小さな単純化についてです ありがとう。
ウィル

2
@Willに同意する必要があります。単純化は非常に小さいため、実行する価値がほとんどありません。
Andres F.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.