0

ワイルドカードをどこで使用する必要があるか、どこで super を使用する必要があるか、ワイルドカードを使用することがまったく不適切な場所はどこですか?

それらの原則または規則、またはそれはすべて、自分自身の理解と適用範囲に関連しています。

現在、リストに追加するのに必要な数字は2つだけなので、使用します。

 public List<Integer> addToNewList(integerList  , Integer element){
   integerList.add(element);
   return integerList;
}

しかし、後でアプリケーションの範囲が拡大し、すべての番号が必要になるため、最大のサポートのために汎用にします。元 :

public <T extends Number> List<T> addToList(List<? extends T> genericList , T element){
   genericList.add(element);
   return genericList;
}

要するに、いつこれらのワイルドカードを使用する必要があり、いつ使用しないのかを知りたいだけです。

4

2 に答える 2

4

私はいつ使うべきか、いつ使わないべきかを理解していました.1冊の本で見つけた素晴らしい原則が1つあります。

Get and Put の原則:構造体から値を取得するだけの場合は extends ワイルドカードを使用し、値を構造体に入れるだけの場合は super ワイルドカードを使用し、get と put の両方を行う場合はワイルドカードを使用しないでください。

数値のコレクションを取得し、それぞれを double に変換して合計するメソッドを次に示します。

public static double sum(Collection<? extends Number> nums) {
    double s = 0.0;
    for (Number num : nums) s += num.doubleValue();
    return s;
}

これは extends を使用するため、次の呼び出しはすべて有効です。

List<Integer>ints = Arrays.asList(1,2,3);
assert sum(ints) == 6.0;
List<Double>doubles = Arrays.asList(2.78,3.14);
assert sum(doubles) == 5.92;
List<Number>nums = Arrays.<Number>asList(1,2,2.78,3.14);
assert sum(nums) == 8.92;

extends が使用されていない場合、最初の 2 つの呼び出しは有効ではありません。

EXCEPTION : extends ワイルドカードで宣言された型に何も入れることはできません — すべての参照型に属する値 null を除きます。

add メソッドを使用するときは常に値を構造体に入れるので、スーパー ワイルドカードを使用します。以下は、数値のコレクションと整数 n を受け取り、ゼロから始まる最初の n 個の整数をコレクションに入れるメソッドです。

public static void count(Collection<? super Integer> ints, int n) {
    for (int i = 0; i < n; i++) ints.add(i);
}

これは super を使用するため、次の呼び出しはすべて有効です。

List<Integer>ints = new ArrayList<Integer>();
count(ints, 5);
assert ints.toString().equals("[0, 1, 2, 3, 4]");
List<Number>nums = new ArrayList<Number>();
count(nums, 5); nums.add(5.0);
assert nums.toString().equals("[0, 1, 2, 3, 4, 5.0]");
List<Object>objs = new ArrayList<Object>();
count(objs, 5); objs.add("five");
assert objs.toString().equals("[0, 1, 2, 3, 4, five]");

super が使用されていない場合、最後の 2 つの呼び出しは有効ではありません。

例外 :すべての参照型のスーパー型である Object 型の値を除いて、スーパー ワイルドカードで宣言された型からは何も取得できません。

この原則は、次の質問でも説明されていますGet and Put ルール

于 2013-09-03T07:12:25.197 に答える
2

意味があるときに使用する必要があります...

あなたのインスタンスでは、アプリケーションの進化により、ジェネリック型を整数から数値に変更するためにコードをリファクタリングする必要があると言いました。これは私にとってはまったく問題ありません。アプリケーションが進化する可能性があるすべての方法を期待することは、ほぼ不可能です。「将来可能性がある」シナリオを処理するコードを記述しても、その時点に到達しない可能性があるため、将来その時点に近づくまでは無駄です。

そうは言っても、関数の機能が適切に実行できる最も制限の少ないタイプに API を設計するようにしてください。もちろん、かなり多くの労力が必要であり、現在の機能では提供されている柔軟性が役に立たない場合を除きます。

于 2013-09-03T06:25:53.983 に答える