2

ジェネリック クラスの生の型はジェネリック クラスのすべての異なるバリエーションを取る (ポイントする) ことができ、ジェネリック クラスのすべての異なるバリエーションはジェネリック クラスの生の型を取る (ポイントする) ことができることに気付きました。Javaジェネリックがそのように動作するのはなぜですか? 純粋に古いバージョンの Java との互換性のためですか?

例:

//Main.java
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {

    List listRaw = new ArrayList();
    List<Student> listQualified = new ArrayList<Student>();
    List<?> listUnbounded = new ArrayList<Student>();
    List<? extends Student> listUpBounded = new ArrayList<Student>();
    List<? super Student> listDownBounded = new ArrayList<Student>();

    // List raw type can take all different variations of List
    List rawList1 = listRaw;
    List rawList2 = listQualified;
    List rawList3 = listUnbounded;
    List rawList4 = listUpBounded;
    List rawList5 = listDownBounded;

    // All different variations of List can take List raw type
    listRaw = rawList1;
    listQualified = rawList2;
    listUnbounded = rawList3;
    listUpBounded = rawList4;
    listDownBounded = rawList5;

    }

}

//People.java
public class People {

    public static class Student extends People {
    }

    public class HistoryStudent extends Student {
    }

    public class MathStudent extends Student {
    }
}
4

2 に答える 2

4

Sun のエンジニアが直面した主な課題の 1 つは、下位互換性を維持することでした。たとえば、割り当てることができない場合:

List list = new ArrayList<Student>();

そうすると、古いライブラリ メソッドを使用できなくなります。すなわち:

List org.apache.commons.collections.ListUtils.intersection(List arg0, List arg1)

また、 http: //docs.oracle.com/javase/tutorial/java/generics/erasure.html で説明されているように、これらの型は実行時に消えることを覚えておいてください。

于 2012-07-09T22:20:13.367 に答える
1

はい。実際、ジェネリックは Java 5 で追加され、言語は古いリリースとのランタイム互換性を維持する必要がありました。いくつかのメソッドがジェネリック型パラメーターを受け入れるかどうかに関係なく infoby リフレクションを使用できる場合でも、コードが .class にコンパイルされると (型消去)、実際にはジェネリック情報が消えるため、この妥協は機能します。あなたが書いたものと同様のコードをコンパイルすると、正常に動作しますが、通常、コンパイラは「生の」型を使用していることを警告します。

于 2012-07-09T22:10:57.833 に答える