为啥java类不从实现的接口继承注解?
Posted
技术标签:
【中文标题】为啥java类不从实现的接口继承注解?【英文标题】:Why java classes do not inherit annotations from implemented interfaces?为什么java类不从实现的接口继承注解? 【发布时间】:2011-06-12 08:39:38 【问题描述】:我正在使用依赖注入框架(Guice 的 AOP 专门拦截一些方法调用)。我的类实现了一个接口,我想注释接口方法,以便框架可以选择正确的方法。即使注解类型使用Inherited注解实现类也不会继承Inherited的Java文档中所述的注解:
还要注意这个元注释 只会导致注释 从超类继承; 已实现接口的注释 没有效果。
这可能是什么原因?了解一个对象的类在运行时实现的所有接口并不是一件难事,所以这个决定背后一定有充分的理由。
【问题讨论】:
【参考方案1】:我会说原因是否则会出现多重继承问题。
示例:
@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”?
因此,接口上的注释很少有用。
【讨论】:
接口注释只有在你有一个支持它们的框架时才有用。顺便说一句,在这个例子中 getAnnotation() 返回 null ;) 我不知道,各位。在这种情况下(如果不存在拼写错误),我预计会出现类似The field value is ambiguous.
的编译器错误,就像两个接口声明具有不同值的相同常量一样。我知道这是 not 字段,但注释值在编译时得到全部解析,不是吗?我们在这里缺少的功能在许多情况下会非常有用。顺便说一句,很抱歉恢复旧帖子:)。
@Slanec 查看 Spring 资源的方式,了解 Spring 人员如何解决这些问题。见AnnotationUtils.findAnnotation(method, annotationType)
我正在考虑写一些类似的东西。通过某种简单的缓存,这对我来说似乎是一种方法。谢谢!在上面的示例中,它将找到Foo
的注释(MyClass
没有注释,然后按照它们在implements
之后的顺序搜索和获取接口)并因此打印“baz”。酷。
@WChargin 是的,只用了 2 年的时间就有人发现了那个错字 :-)【参考方案2】:
来自@Inherited 的Javadoc:
表示一个注解类型是自动继承的。如果 注释类型上存在继承的元注释 声明,用户查询类上的注解类型 声明,并且类声明对此没有注释 类型,则将自动查询该类的超类 注释类型。这个过程会一直重复,直到有注解 找到此类型,或者类层次结构(对象)的顶部是 到达。如果没有超类有这个类型的注解,那么 查询将表明有问题的类没有这样的注释。 请注意,如果已注释,则此元注释类型无效 type 用于注释除类以外的任何内容。另请注意 此元注释仅导致注释从 超类;已实现接口上的注释无效。
另一方面,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
元注释。
【讨论】:
这个应该是选择的答案 您的示例与您的回答相矛盾,即@Inherited
对类以外的任何内容都没有影响
@Inherited 仅在您在 Class 上使用注解时有效
回答OP关于接口注释的问题怎么样!?以上是关于为啥java类不从实现的接口继承注解?的主要内容,如果未能解决你的问题,请参考以下文章