重复注解需要公共容器吗? [英] Do repeating annotations need a public container?

查看:29
本文介绍了重复注解需要公共容器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用重复注释时,我注意到 Eclipse 的编译器和 javac 之间存在差异.重复注解和它的容器在同一个包中,但前者被声明为公开的,而后者则保持包私有.即使在另一个包中引用了重复的注释,Eclipse 的安排也没有问题.另一方面,javac 拒绝编译,说

I noticed a discrepancy between Eclipse's compiler and javac while using repeating annotations. The repeating annotation and its container were in the same package, but the former was declared public, while the latter remained package-private. Eclipse had no problem with the arrangement, even though the repeating annotation was referenced in another package. javac, on the other hand, refused to compile, saying

[container] 中的 value() 定义在不可访问的类或接口中

value() in [container] is defined in an inaccessible class or interface

我的问题是,哪个是正确的?我在 JLS 中找不到任何关于此的规则.这是否意味着它可以解释?还是其中一个编译器存在错误?

My question is, which one is correct? I couldn't find any rule about this in the JLS. Does that mean it's open to interpretation? Or is there a bug in one of the compilers?

推荐答案

没有关于可访问性的声明,但规范明确指出,repeatable 注释可能被限制为可重复由于包含注释的声明方式,仅在某些位置.

There is no statement regarding accessibility but the specification makes it clear that it is possible that a repeatable annotation may be restricted to be repeatable at certain locations only, due to the way how the containing annotation has been declared.

JLS §9.6.3

  1. T 至少适用于与 TC 相同类型的程序元素(第 9.6.4.1 节).具体来说,如果T适用的程序元素种类用集合m1表示,TC适用的程序元素种类用集合m2表示,那么m2中的每一种都必须出现在m1中,……

  1. 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, …

该子句实现了注释类型可能仅在其适用的某些类型的程序元素上可重复的策略

这也是 以示例支持:

类型声明表示java.lang.annotation.ElementType.TYPE目标的注解可以出现在至少与类型声明表示java目标的注解一样多的位置.lang.annotation.ElementType.ANNOTATION_TYPE.例如,给定以下可重复和包含注释类型的声明:

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 可以出现在任何类型声明中,而 @FooContainer 只能出现在注解类型声明中.因此,以下注解类型声明是合法的:

@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 强加的限制而不是可访问性修饰符,但它描述了一种也可以应用于后者的精神".意图显然似乎是可重复的注释只有在指定的容器注释的属性允许的情况下才能重复,否则仍然可以使用该注释,但只能出现一次.

While this is discussing restrictions imposed by @Target rather than accessibility modifiers, it describes a "spirit" that can be applied to the latter as well. The intention clearly seems to be that a repeatable annotation can only be repeated if the properties of the specified container annotation allow it, otherwise the annotation still may be used, but only with a single occurrence.

这不像可重复注解的属性能够覆盖容器注解类型的属性.这与所有其他地方的行为一致;即使源代码中没有对不可访问的注释类型的引用,编译重复的注释也会在类文件中创建一个引用,并且类文件可能不包含对不可访问类的符号引用,并且不应该只对容器注解.

It’s not like the properties of a repeatable annotation were capable of overriding the properties of the container annotation type. This is in line with the behavior at all other places; even if there is no reference to the inaccessible annotation type in the source code, compiling the repeated annotation would create a reference in the class file and a class file may not contain symbolic references to inaccessible classes and there shouldn’t be an exception only for container annotations.

这篇关于重复注解需要公共容器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆