2

最近、Java Web サービスの調査を開始したところ、次の不可解な情報が見つかりました。

@Consumes アノテーションを持つインターフェースで定義されたメソッドがあり、そのインターフェースを実装すると、@Consumes が継承されているかのように、サービスは正しく機能します。

ただし、さまざまな記事とここを読むと、注釈は継承されていないようです。

これを確認するために、次のテストをノックアップしました。

interface ITestAnnotationInheritance {
    @Consumes
    void test();
}

class TestAnnotationInheritanceImpl implements ITestAnnotationInheritance {
    @Override
    //@Consumes     // This doesn't appear to be inherited from interface
    public void test() {}

    public static void main(String[] args) throws SecurityException, NoSuchMethodException {
        System.out.println(TestAnnotationInheritanceImpl.class.getMethod("test").getAnnotation(Consumes.class));
    }
}

結果は次のとおりです。

null

TestAnnotationInheritanceImpl クラスの @Consumes のコメントを外すと、出力は次のようになります。

@javax.ws.rs.Consumes(value=[*/*])

これはアノテーションが継承されていないことを証明していますが、なぜ Web サービスは正常に動作するのでしょうか?

どうもありがとう

4

1 に答える 1

2

メソッドのWebサービスアノテーションについて話していると仮定すると、フレームワークはおそらくリフレクションを使用して、スーパークラスで宣言されたメソッドのアノテーションを見つけます...または継承階層を追跡して、実装またはオーバーライドされたメソッドで宣言されたアノテーションを探します同じサイン。(フレームワークのソース コードを見れば、正確に何が起こっているかを理解できるでしょう...)


あなたの例のこのバリエーションを試してください:

class TestAnnotationInheritance {
    @Consumes
    public void test() {}
}

class TestAnnotationInheritance2 extends TestAnnotationInheritance {
    public static void main(String[] args) 
    throws SecurityException, NoSuchMethodException {
        System.out.println(TestAnnotationInheritance2.class.getMethod("test").
                           getAnnotation(Consumes.class));
    }
}

これにより、アノテーションがメソッドに存在することが示されると思います。(ここでの違いは、 @Consumes アノテーションを持つメソッド宣言を、それを持たない別の宣言でオーバーライドしないことです。)


クラスの注釈は通常継承されませんが、@Inherited注釈で宣言されている場合は継承されることに注意してください。JLS 9.6.3.3およびjavadocを参照してください。

IMO、注釈の継承の概念はすべて少しゴムです。しかし幸いなことに、コア Java 型システムと計算モデルには影響しません。

于 2012-11-28T13:07:42.137 に答える