3

以下のスニペットを検討してください。ジェネリック型に関してオーバーライドがどのように機能するか、および戻り値の型List<String>(たとえば) がオーバーライドできる理由を理解していますList<? extends Object>。ただし、1 や 2 などのステートメントがコンパイルに失敗する理由は完全にはわかりません...ここでも継承が適用されるべきではないのでしょうか?

public class Generics {

    public static void main(String[] args) {

        A instance = new B();
        X instance2 = new Y();

        Map<String, String> map = instance2.getMap(); // 1
        List<String> list = instance.getList();       // 2
    }
}

class A {

    List<? extends Object> getList() {

        return null;
    }
}

class B
        extends A {

    List<String> getList() {

        return new LinkedList<String>();
    }
}

class X {

    Map<String, ? extends Object> getMap() {

        return null;
    }
}

class Y
        extends X {

    @Override
    Map<String, String> getMap() {

        return null;
    }
}
4

3 に答える 3

3
Map<String, String> map = instance2.getMap(); // 1

コンパイラはX.getMap()、戻り値の型がの呼び出しを認識しますMap<String, ? extends Object>。これは に変換できませんMap<String, String>。実行時instance2の型であるかどうかは問題ではありません。Yこれは純粋なコンパイル時の静的型チェックであり、失敗しています。

List<String> list = instance.getList();       // 2

同じ理由が当てはまります。のコンパイル時の型は でinstanceありA、 と互換性A.getList()のない を返します。List<? extends Object>List<String>

ジェネリックに固有の問題ではないことに注意してください。これも同じ理由でコンパイルに失敗します。

class A { Object getObject(); }
class B extends A { String getObject(); }

A a = new B();
String s = a.getObject();

機能させたい場合は、コンパイラに追加のヘルプを提供する必要があります。サブクラスにキャストすることによって:

String s = ((B) a).getObject();

または、戻り値をキャストすることによって:

String s = (String) a.getObject();
于 2012-11-27T19:30:05.060 に答える
1

ポリモーフィズムは逆方向には機能しません。

を拡張した別のクラスでそれを試みたXが、\ が返された場合はどうなりますか?

Map<String, NonString>

代わりは?

于 2012-11-27T19:28:46.553 に答える