Java继承接口中的注释

时间:2012-11-28 12:59:08

标签: java web-services annotations

我最近开始研究Java Web Services并发现以下令人费解的问题:

如果我在具有@Consumes注释的接口中定义了一个方法,然后我实现了该接口,则该服务正常工作,就像继承了@Consumes一样。

但是,通过阅读各种文章和here,似乎注释不会被继承。

我敲了下面的测试来检验出来:

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服务如何正常工作?

非常感谢

1 个答案:

答案 0 :(得分: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.3javadoc

IMO,注释的继承概念有点浮躁。但幸运的是,它不会影响核心Java类型系统和计算模型。