2

次のコードを検討してください。

class ExtType extends MyType{};

class MyClass {
    MyType myField;

    public <T extends MyType> T foo(Class<T> clazz) {
        return (T)myField;
    }
}

メソッドを呼び出したいのですfooが、これは次の 2 つの方法で実行できます。

片道:

(new MyClass()).foo(ExtType.class);

2ウェイ:

(new MyClass()).<ExtType>foo(ExtType.class);

興味深いことに、メソッドがパラメーター化されていると宣言されていても、Eclipse は 1 回の呼び出しで警告を発行しません。

これが私の質問です。最初のコードスニペットで、T戻り値のキャストに使用されるのはどれですか。それはTfrom パラメータTですか、それとも戻り値ですか? 戻り値の型を (「一方向」のように) 明示的に指定しないと、警告が発行されないのはなぜですか?

4

2 に答える 2

4

通常はパラメーターの型が使用されますが、(方法 2 のように) 戻り値の型が定義されている場合、コンパイラはそれもチェックします。

戻り値の型宣言は、型を取得するパラメーターがない場合に必要になりますT。これは、型推論と呼ばれます。したがって、次のように書くこともできます。

public <T extends MyType> T foo() {
    return (T)myField;
}


ExtType t = (new MyClass()).foo();

場合によっては、コンパイラを支援し、使用する型を指定して、 のようなコードを取得する必要があります(new MyClass()).<ExtType>foo(ExtType.class);。ただし、異なるタイプを定義すると、たとえば(new MyClass()).<MyType>foo(ExtType.class);、コンパイラはどちらが使用されているかを認識できないため、コンパイル時にエラーが発生することに注意してください。

于 2012-04-10T08:26:59.040 に答える
1

関数宣言で 'T' を定義すると、それが保持して返す T 型も定義されます。あなたの場合、パラメーターを渡し、同じ戻り値の型を期待しており、拡張された ExtType として 'T' を宣言しています。したがって、Eclipse は警告を生成しません。

于 2012-04-10T08:27:52.193 に答える