重复注释是否需要 public 容器?
Do repeating annotations need a public container?
我注意到在使用重复注释时 Eclipse 的编译器和 javac 之间存在差异。重复注释和它的容器在同一个包中,但前者被声明为 public,而后者仍然是包私有的。 Eclipse 的安排没有问题,即使在另一个包中引用了重复注释。另一方面,javac 拒绝编译,说
value() in [container] is defined in an inaccessible class or interface
我的问题是,哪一个是正确的?我在 JLS 中找不到关于此的任何规则。这是否意味着它可以解释?还是其中一个编译器中存在错误?
没有关于可访问性的声明,但规范清楚地表明,可重复 注释可能被限制为只能在某些位置重复,由于如何声明 containing 注释。
…
T is applicable to at least the same kinds of program element as TC (§9.6.4.1). Specifically, if the kinds of program element where T is applicable are denoted by the set m1, and the kinds of program element where TC is applicable are denoted by the set m2, then each kind in m2 must occur in m1, …
This clause implements the policy that an annotation type may be repeatable on only some of the kinds of program element where it is applicable
Example 9.6.3-2. Restricting Where Annotations May Repeat
An annotation whose type declaration indicates a target of java.lang.annotation.ElementType.TYPE
can appear in at least as many locations as an annotation whose type declaration indicates a target of java.lang.annotation.ElementType.ANNOTATION_TYPE
. For example, given the following declarations of repeatable and containing annotation types:
@Target(ElementType.TYPE)
@Repeatable(FooContainer.class)
@interface Foo {}
@Target(ElementType.ANNOTATION_TYPE)
@Interface FooContainer {
Foo[] value();
}
@Foo
can appear on any type declaration while @FooContainer
can appear on only annotation type declarations. Therefore, the following annotation type declaration is legal:
@Foo @Foo
@interface X {}
while the following interface declaration is illegal:
@Foo @Foo
interface X {}
虽然这是在讨论 @Target
而不是可访问性修饰符施加的限制,但它描述了一种也可以应用于后者的“精神”。意图显然是,只有在指定容器注释的属性允许的情况下,才可以重复可重复注释,否则仍然可以使用该注释,但只能出现一次。
可重复注解的属性并不能覆盖容器注解类型的属性。这与所有其他地方的行为一致;即使在源代码中没有引用不可访问的注释类型,编译重复的注释也会在 class 文件中创建一个引用,并且 class 文件可能不包含对不可访问的 [=36] 的符号引用=]是的,不应该只对容器注释有例外。
我注意到在使用重复注释时 Eclipse 的编译器和 javac 之间存在差异。重复注释和它的容器在同一个包中,但前者被声明为 public,而后者仍然是包私有的。 Eclipse 的安排没有问题,即使在另一个包中引用了重复注释。另一方面,javac 拒绝编译,说
value() in [container] is defined in an inaccessible class or interface
我的问题是,哪一个是正确的?我在 JLS 中找不到关于此的任何规则。这是否意味着它可以解释?还是其中一个编译器中存在错误?
没有关于可访问性的声明,但规范清楚地表明,可重复 注释可能被限制为只能在某些位置重复,由于如何声明 containing 注释。
…
T is applicable to at least the same kinds of program element as TC (§9.6.4.1). Specifically, if the kinds of program element where T is applicable are denoted by the set m1, and the kinds of program element where TC is applicable are denoted by the set m2, then each kind in m2 must occur in m1, …
This clause implements the policy that an annotation type may be repeatable on only some of the kinds of program element where it is applicable
Example 9.6.3-2. Restricting Where Annotations May Repeat
An annotation whose type declaration indicates a target of
java.lang.annotation.ElementType.TYPE
can appear in at least as many locations as an annotation whose type declaration indicates a target ofjava.lang.annotation.ElementType.ANNOTATION_TYPE
. For example, given the following declarations of repeatable and containing annotation types:@Target(ElementType.TYPE) @Repeatable(FooContainer.class) @interface Foo {} @Target(ElementType.ANNOTATION_TYPE) @Interface FooContainer { Foo[] value(); }
@Foo
can appear on any type declaration while@FooContainer
can appear on only annotation type declarations. Therefore, the following annotation type declaration is legal:@Foo @Foo @interface X {}
while the following interface declaration is illegal:
@Foo @Foo interface X {}
虽然这是在讨论 @Target
而不是可访问性修饰符施加的限制,但它描述了一种也可以应用于后者的“精神”。意图显然是,只有在指定容器注释的属性允许的情况下,才可以重复可重复注释,否则仍然可以使用该注释,但只能出现一次。
可重复注解的属性并不能覆盖容器注解类型的属性。这与所有其他地方的行为一致;即使在源代码中没有引用不可访问的注释类型,编译重复的注释也会在 class 文件中创建一个引用,并且 class 文件可能不包含对不可访问的 [=36] 的符号引用=]是的,不应该只对容器注释有例外。