5

次のコードがあります。

class SuperClass {
    public static String getName() { return "super"; }
}

class SubClass extends SuperClass {
    public static String getName() { return "sub"; }
}

public class Dummy<T extends SuperClass> {
    public void print() {
        System.out.println("SuperClass: " + SuperClass.getName());
        System.out.println("SubClass: " + SubClass.getName());
        System.out.println("T: " + T.getName());
    }
    public static void main(String[] args) {
        new Dummy<SubClass>().print();
    }
}

このコードは次を出力します。

SuperClass: super
SubClass: sub
T: super

私の質問は: T.getName() が SubClass.getName() の値を返さないのはなぜですか? 結局、T == SubClass と指定しました。それとも、ジェネリック参照に対して静的関数呼び出しは無効ですか?

よろしくお願いします!

4

3 に答える 3

1

C++ テンプレートとは異なり、Java ジェネリックは型消去によって機能するため、 のすべての値に対して 1 つのクラスのみを生成し、このクラスの型へのすべての参照を のスーパー タイプ (この場合は )Tに変換し、仮想ディスパッチを使用して のバリアンスを提供します。オブジェクトメソッドへの呼び出し、および静的メソッドへの呼び出しへの静的ディスパッチ。TTSuperClass

そのため、コンパイラはinをグローバルに置換しDummy<SubClass>.print()ません。コンパイラが行うのは、のメソッドでの引数または戻り値の型としてのの使用をチェックすることだけです。内のコードは変更されていないため、同じ静的メソッドが呼び出されます。TSubClassDummyTDummySubClassDummySuperClassT

パラメーター化された型に応じてジェネリック クラスで異なる動作が必要な場合は、その型のオブジェクトを渡して仮想メソッドを使用するか、型のクラスを渡してリフレクションを使用します。

于 2009-03-24T13:10:11.247 に答える