[解決済み] ジェネリックメソッドとワイルドカードの使い分けは?
質問
ジェネリックメソッドについて、以下の記事を読んでいます。 OracleDocGenericMethod . 私は、ワイルドカードを使用する場合とジェネリックメソッドを使用する場合の比較について、かなり混乱しています。 ドキュメントから引用します。
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
ここでは、代わりにジェネリックメソッドを使うことができました。
interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! }
[...] これはtype引数がポリモーフィズムのために使われていることを物語っています。 その唯一の効果は、実際の引数の様々な型を異なる呼び出し場所で使用できるようにすることです。 を異なる呼び出し位置で使用できるようにすることです。もしそうであれば はワイルドカードを使うべきである。ワイルドカードは柔軟なサブタイピングをサポートするために設計されています。 それがここで表現したいことなのです。
のようなワイルドカードを考えてはいけないのでしょうか?
(Collection<? extends E> c);
も一種の
ポリモーフィズムをサポートしていると思いませんか?では、なぜジェネリックメソッドの使用は良くないとされているのでしょうか?
続けて、こう書かれています。
ジェネリックメソッドでは、型パラメータを使用して、メソッドへの1つ以上の引数の型の間の依存関係を表現することができます。 メソッドへの1つ以上の引数や戻り値の型の間の依存性を表現するために、型パラメータを使用することができます。 およびその戻り値の型の間の依存性を表現するために型パラメータを使用することができます。そのような依存関係がない場合、ジェネリック メソッドは使用されるべきではありません。
これは何を意味するのでしょうか?
例題を提示されました
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[...]
このメソッドの署名は別の方法で書くことができます。 ワイルドカードを全く使わずに。
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
この文書では、2番目の宣言は推奨されず、1番目の構文の使用が推奨されているのですか?最初の宣言と2番目の宣言の違いは何ですか?どちらも同じことをやっているように見えますが?
誰かがこの領域に光を置くことができます。
どのように解決するのですか?
ワイルドカードと型パラメータで同じことができる場所があります。しかし、タイプパラメータを使用しなければならない場所もあります。
- 異なるタイプのメソッド引数に何らかの関係を強制したい場合、ワイルドカードではそれを行うことができず、タイプパラメーターを使用する必要があります。
あなたのメソッドを例にとって、もしあなたが
src
と
dest
に渡されるリスト
copy()
メソッドに渡されるリストは、同じパラメータ化された型である必要があります。
public static <T extends Number> void copy(List<T> dest, List<T> src)
ここでは
dest
と
src
は、同じパラメタライズドタイプを持つ
List
. ですから
src
から
dest
.
しかし、そのままワイルドカードを使用する方法に変更すると
public static void copy(List<? extends Number> dest, List<? extends Number> src)
を指定しても、期待通りに動作しません。2番目のケースは
List<Integer>
と
List<Float>
として
dest
そして
src
. ですから、要素を
src
から
dest
はもう型安全でなくなってしまう。
もし、そのような関係が必要ないのであれば、型パラメータを全く使わないのも自由です。
その他、ワイルドカードと型パラメーターの違いは以下の通りです。
- パラメータ化された型引数が1つしかない場合、型パラメータも機能しますが、ワイルドカードを使用することができます。
- 型パラメータは複数の境界をサポートしますが、ワイルドカードはサポートしません。
-
ワイルドカードは上限と下限の両方をサポートし、型パラメータは上限のみをサポートします。そのため、もしあなたが
List
という型のInteger
またはそのスーパークラスであれば、可能です。public void print(List<? super Integer> list) // OK
のようになりますが、typeパラメータは使えません。
public <T super Integer> void print(List<T> list) // Won't compile
リファレンスです。
関連
-
linux run jarfile Invalid or corrupt jarfile error.
-
ブラウザでの大容量ファイルスライスアップロード(Javaサーバサイド実装)
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] java.net.URLConnectionを使用してHTTPリクエストを発生させ処理する方法
-
[解決済み] なぜゲッターとセッター/アクセッサーを使うのですか?
-
[解決済み] リフレクションを使ってジェネリックメソッドを呼び出すにはどうしたらいいですか?
-
[解決済み] 静的メソッドを使用する場合
-
[解決済み] Java の import 文でワイルドカードを使用することは、なぜ悪いのですか?
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java Error スレッド "AWT-EventQueue-0" で例外発生 java.lang.
-
この行に複数のマーカーがある - HttpServletResponseが型エラーに解決できない
-
ファインバグタイプ
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
Eclipseでプロジェクトエクスプローラービューとパッケージエクスプローラービューを使う
-
Java コンパイルエラー - スレッド "main" で例外 java.lang.Error: 未解決のコンパイル問題です。
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
javaでクラスを作成すると、enclosing classでないように見える
-
javaでよく使われる英単語
-
HttpClientがGZIP形式でない場合の対処法