2

我最近开始研究 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 服务怎么能正常工作呢?

非常感谢

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 注释的声明覆盖具有 @Consumes 注释的方法声明。)


请注意,类上的注解通常不会被继承,但如果它们是用@Inherited注解声明的,它们就会被继承;请参阅JLS 9.6.3.3javadoc

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

于 2012-11-28T13:07:42.137 回答