我最近开始研究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服务如何正常工作?
非常感谢
答案 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.3和javadoc。
IMO,注释的继承概念有点浮躁。但幸运的是,它不会影响核心Java类型系统和计算模型。