3

再帰と同様に機能するジェネリックメソッドがありますが、呼び出しごとにメソッドの異なるインスタンスを呼び出します。

public <M extends A> void doSomething(Class<M> mClass, M mObject)
{
    // ... Do something with mObject.

    A object = getObject();
    Class<? extends A> objectClass = object.getClass();

    doSomething(objectClass, objectClass.cast(object)); // Does not compile.
}

private A getObject() {...}

問題は、コメントのある行がコンパイルされず、次のエラーが発生することです。

MainTest 型のメソッド doSomething(Class, M) は引数に適用されません (Class, capture#3-of ? extends A)

doSomethingM = "? extends A" で呼び出すことができる場合、コンパイラがコンパイルしない理由がよくわかりません。

なぜコンパイルされないのですか?

4

3 に答える 3

4

ここに大まかな説明があります

AのサブタイプであるMを受け入れるようにメソッドを入力しました

ここで、Aのサブタイプである'objectClass'を使用してメソッドを呼び出していますが、必ずしもMのサブタイプである必要はありません。

したがって、コンパイラは文句を言っています...

あなたがやろうとしていることをもう少し説明できれば、私は解決策を手伝うことができます。

于 2013-02-04T04:42:08.263 に答える
2

言語はそのようなワイルドカードを追跡しません (らしい)。必要なことは、そのワイルドカードをキャプチャすることです。これは、型推論によるメソッド呼び出しで実行できます。

public <M extends A> void doSomething(Class<M> mClass, M mObject) {
    // ... Do something with mObject.

    A object = getObject();
    Class<? extends A> objectClass = object.getClass();
    privateSomething(objectClass, object);
}
private <T extends A> void privateSomething(Class<T> objectClass, A object) {
    doSomething(objectClass, objectClass.cast(object)); // Should compile.
}

いつものように、リフレクションにはいくつかの用途がありますが、通常は混乱の兆候です。

于 2013-02-04T05:14:19.463 に答える
1

コンパイラにキャストを実行するように要求する場合、キャストを実行する正確な型がわかっている必要があります。A のサブクラスであるという正確な型の抜粋を知らないことをコンパイラに伝えるだけでは十分ではありません。

クラスは、オブジェクトの型が A のサブクラスであることをコンパイラーに伝えますが、キャストに使用される正確な型をコンパイラーに伝えません。

あなたの問題は、ポリモーフィズムをジェネリックに置き換えようとしていることです。あなたが苦労して学んでいるように、ジェネリックはポリモーフィズムを行う新しい現代的な方法ではありません。

于 2013-02-04T05:00:52.250 に答える