为什么Java类不从实现的接口继承注释?


108

我一直在使用Guice的AOP来拦截一些方法调用。我的课程实现了一个接口,我想注释接口方法,以便Guice可以选择正确的方法。即使使用继承的注释对注释类型进行注释,实现类也不会继承Inherited的java doc中所述的注释:

另请注意,此元注释仅使注释从超类继承;已实现的接口上的注释无效。

这可能是什么原因?了解对象的类在运行时确实实现的所有接口并不是一件难事,因此,在做出此决定后一定有充分的理由。

Answers:


130

我要说的原因是,否则会发生多重继承问题。

例:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Inherited
public @interface Baz { String value(); }

public interface Foo{
    @Baz("baz") void doStuff();
}

public interface Bar{
    @Baz("phleem") void doStuff();
}

public class Flipp{
    @Baz("flopp") public void doStuff(){}
}

public class MyClass extends Flipp implements Foo, Bar{}

如果我这样做:

MyClass.class.getMethod("doStuff").getAnnotation(Baz.class).value()

结果将是什么?'baz','phleem'或'flopp'?


因此,接口上的注释很少有用。


9
接口上的注释仅在具有支持它们的框架时才有用。BTW在此示例中,getAnnotation()返回null;)
Peter Lawrey 2011年

6
我不知道,人们。在这种情况下(如果没有输入错误),我期望The field value is ambiguous.出现类似-like的编译器错误,就像两个接口声明具有不同值的相同常量一样。我知道这不是一个字段,但是注释值会在编译时全部解析出来,不是吗?在许多情况下,我们在此处缺少的功能将非常有用。抱歉,关于恢复旧帖子的问题:)。
PetrJaneček'04

7
@Slanec看看Spring的来源,看看Spring的人如何解决这些问题。参见AnnotationUtils.findAnnotation(method,注解类型)
Sean Patrick Floyd

1
我当时正在考虑写与此类似的东西。通过某种简单的缓存,这对我来说似乎是一种方法。谢谢!在上面的示例中,它将找到Foo的注释(MyClass没有注释,然后按照在接口之后的顺序搜索和获取接口implements),因此打印“ baz”。凉。
PetrJaneček'12

2
@WChargin是真的,有人花了两年时间才发现错字:-)
肖恩·帕特里克·弗洛伊德

35

Javadoc中获取@Inherited:

指示注释类型是自动继承的。如果注释类型声明中存在继承的元注释,并且用户在类声明中查询该注释类型,并且该类声明没有该类型的注释,则将自动查询该类的超类以获取注释类型。重复此过程,直到找到该类型的注释,或到达类层次结构(对象)的顶部为止。如果没有超类对此类型进行注释,则查询将指示所讨论的类没有此类注释。请注意,如果带注释的类型用于注释除类之外的任何内容,则此元注释类型无效。另请注意,此元注释仅使注释从超类继承;

另一方面,JSR 305验证器进行某种继承查找。如果您具有类的层次结构:

//Person.java
@Nonnull
 public Integer getAge() {...}

//Student.java (inherits from Person)
@Min(5)
public Integer getAge() {...}

然后的有效验证Student.getAge()@Nonnull @Min(5)@Nonnull没有@Inherited元注释。


4
这应该是选定的答案
Andrzej Purtak '16

3
您的示例与您的回答相矛盾,该回答说,@Inherited除了上课之外,这对其他任何事情都没有影响
Oleg Mikheev

@Inherited仅在您在课堂上使用注释时才有效
Carlos Parker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.