2

継承を使用していくつかのジェネリックを作成しましたが、タイプセーフに動作させることができません。私の目標は、オブジェクトが であるかであるかに関係なく、メソッドBaseServiceを実行できるという一般的なことを提供することです。action(base)baseFoo extends BaseBar extends Base

以下は機能しません。なぜですか?

class Base;
class Foo extends Base;

interface BaseService<T extends Base> {
    void action(T base);
}

class FooService implements BaseService<Foo> {
    void action(Foo foo) {
    }
}


//usage:
//complains that the method is not applicable for the argument,
//and that I should change action(T) to action(Base). Why?
Base base;
getService().action(base);


//just to demonstrate the problem
BaseService<? extends Base> getService() {
    return new FooService();
}
4

1 に答える 1

1

ジェネリックは、静的な型チェックを目的として存在します。あなたが書いているように

私の目標は、ベース オブジェクトが Foo extends Base であるか Bar extends Base であるかに関係なく、action(base) メソッドを実行できる一般的な BaseService を提供することです。

静的型チェックが不要であることを示します。したがって、それを実現するには、引数の型をBaseの代わりにする必要がありTます。

の戻り値の型がgetService()isBaseService<? extends Base>であるため、コンパイラTは ( の未知のサブタイプであることを除いて)が何であるかを知ることさえBaseできないため、メソッドをまったく呼び出すことはできませんaction。しかし、 の戻り値の型が であってもgetService()FooService引数の型Tは であるFooため、 type で呼び出すことはできませんBase

おそらく、ジェネリックを使用してコンパイラに実際にチェックしてもらいたいことについて、もう少し考えるべきです。

于 2013-04-02T12:45:39.797 に答える