ChatGPT解决这个技术问题 Extra ChatGPT

为什么java类不从实现的接口继承注解?

我正在使用依赖注入框架(Guice 的 AOP 专门拦截一些方法调用)。我的类实现了一个接口,我想注释接口方法,以便框架可以选择正确的方法。即使注释类型使用 Inherited 注释实现类进行注释,也不会继承 Inherited 的 java 文档中所述的注释:

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

这可能是什么原因?了解一个对象的类在运行时实现的所有接口并不是那么难的事情,所以这个决定背后一定有一个很好的理由。


t
thSoft

我会说原因是否则会出现多重继承问题。

例子:

@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 年的时间 :-)
t
thSoft

来自 @Inherited 的 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 元注释。


这个应该是选择的答案
您的示例与您的答案相矛盾,这表明 @Inherited 对除类以外的任何内容都没有影响
@Inherited 仅在您使用 Class 上的注释时才有效
回答OP关于接口注释的问题怎么样!?