[java] Java 클래스가 구현 된 인터페이스에서 주석을 상속하지 않는 이유는 무엇입니까?

나는 일부 메서드 호출을 가로 채기 위해 Guice의 AOP를 사용하고 있습니다. 내 클래스는 인터페이스를 구현하고 Guice가 올바른 메서드를 선택할 수 있도록 인터페이스 메서드에 주석을 달고 싶습니다. 주석 유형이 Inherited 주석 구현 클래스로 주석 이 달린 경우에도 Inherited의 Java 문서에 명시된 주석을 상속하지 않습니다.

또한이 메타 주석은 주석이 수퍼 클래스에서 상속되도록합니다. 구현 된 인터페이스에 대한 주석은 효과가 없습니다.

그 이유는 무엇일까요? 객체의 클래스가 런타임에 구현하는 모든 인터페이스를 아는 것은 그렇게 어려운 일이 아니므로이 결정 뒤에는 좋은 이유가 있어야합니다.



답변

그 이유는 그렇지 않으면 다중 상속 문제가 발생하기 때문입니다.

예:

@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’?


이러한 이유로 인터페이스의 주석은 거의 유용하지 않습니다.


답변

@Inherited에 대한 Javadoc 에서 :

주석 유형이 자동으로 상속됨을 나타냅니다. 상속 된 메타 주석이 주석 유형 선언에 있고 사용자가 클래스 선언에 대한 주석 유형을 쿼리하고 클래스 선언에이 유형에 대한 주석이없는 경우 클래스의 수퍼 클래스가 주석 유형에 대해 자동으로 쿼리됩니다. 이 프로세스는이 유형에 대한 주석을 찾거나 클래스 계층 (Object)의 최상위에 도달 할 때까지 반복됩니다. 이 유형에 대한 주석이있는 수퍼 클래스가없는 경우 쿼리는 해당 클래스에 그러한 주석이 없음을 나타냅니다. 이 메타 어노테이션 유형은 어노테이션이있는 유형이 클래스가 아닌 다른 것을 어노테이션하는 데 사용되는 경우 효과가 없습니다. 또한이 메타 주석은 주석이 수퍼 클래스에서 상속되도록합니다.

반면에 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.


답변