9

ジェネリックのチュートリアル Q&A から演習問題を解こうとしていたところ、私の答えは少し違っていました

私の答え

public static <T extends Comparable<? super T>>
    T max(List<? extends T> list, int begin, int end) //Option1

public static <T extends Comparable<T>>
    T max(List<? extends T> list, int begin, int end) //Option2

以下の引用された回答から

だから私の質問は

  • T extends Object & Comparable<? super T>オプション 1 :を に置き換えても違いはありますかT extends Comparable<? super T>extends Object暗黙的ではありませんか?

  • Comparable<? super T>オプション 2 :を に置き換えても違いはありComparable<T>ますか? もしそうならどのように?

  • List<? extends Comparable<? super Comparable<? super T>>> list;Eclipse コード補完は、Ctrl+1max(list, 1, 10);でビット長のローカル変数を作成します。Comparable<? super T>を拡張し、リストを作成してインスタンスをリストに追加し、以下のメソッドを呼び出すクラス (階層) を定義する方法は? max()基本的に、クラスインスタンスA or B をリストに追加した後に呼び出す方法を知りたいclass B extends A


リストの [begin, end) の範囲で最大の要素を見つけるジェネリック メソッドを作成します。

答え:

import java.util.*;

public final class Algorithm {
    public static <T extends Object & Comparable<? super T>>
        T max(List<? extends T> list, int begin, int end) {

        T maxElem = list.get(begin);

        for (++begin; begin < end; ++begin)
            if (maxElem.compareTo(list.get(begin)) < 0)
                maxElem = list.get(begin);
        return maxElem;
    }
}
4

2 に答える 2

8

Comparable<? super T>を に置き換えても違いはありComparable<T>ますか? もしそうならどのように?

Comparablesは常に消費者、つまりインスタンスをComparable<T>消費することを忘れないでください。スーパークラスが. 次のコードを検討してください。TComparable<? super T>Comparable<T>Comparable<SuperType>

class Parent implements Comparable<Parent> {
    protected String name;

    @Override
    public int compareTo(Parent o) {
        return this.name.compareTo(o.name);
    }
}

class Child extends Parent {
    public Child(String name) {
        this.name = name;
    }
}

型パラメーターを として指定すると、T extends Comparable<T>そのメソッドを に対して呼び出すことはできません。 Childは実装していませんが、:List<Child>Comparable<Child>Comparable<Parent>

public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) {
    ...
}

public static void main(String[] args) {
    List<Child> list = new ArrayList<Child>();
    max(list, 0, 2);  // Error with current method. Child does not implement Comparable<Child>
}

したがって、型パラメーターの境界は である必要がありますT extends Comparable<? super T>

Childクラスを次のように変更できないことに注意してください。

class Child extends Parent implements Comparable<Child>

その場合、クラスは同じジェネリック型の異なるインスタンス化から拡張されるため、これは許可されていません。


T extends Object & Comparable<? super T>に置き換えても違いはありますかT extends Comparable<? super T>。extends Object は暗黙的ではありませんか?

さて、2 つの境界には違いがあります。1番目の境界では、型パラメーターの消去は ですがObject、2番目の境界では、消去はComparableです。

したがって、制限なくObject、コードは次のようにコンパイルされます。

public static Comparable max(List list, int begin, int end)

この問題は、従来の非ジェネリック コードを生成しているときに発生する可能性があります。Objectバイトコードの互換性を壊さないように、上限としても指定する必要があります。このリンクで詳細を読むことができます: Angelika Langer - Programming Idioms

于 2013-08-23T20:52:21.247 に答える
0

必要以上のワイルドカードがあるようです。私はおそらく一緒に行きます

public static <T extends Comparable<? super T>>
    T max(List<T> list, int begin, int end)

さらに制限されたバージョン:

public static <T extends C, C extends Comparable<C>>
    T max(List<T> list, int begin, int end)

つまり、それ自体Tに匹敵するスーパー タイプが必要です。たとえば、することはできませんTFoo

    class Foo implements Comparable<Object>

とにかく Foo は意味がありません。Comparable は、それ自身の種類とのみ意味のある比較ができます。この条項C extends Comparable<C>は、その事実を認めています。

于 2013-08-23T21:45:03.613 に答える