1

我在JLS 第 8.4 节中看到,省略号之前可以有注释:

class X {
    void method(String @Annotation ... x) {}
}

我的问题很简单:这是什么意思?

特别是,有什么区别:

class X {
    void method(@Annotation String ... x) {}
}
4

2 回答 2

3

来自 JLS 关于注释可能出现的位置

注释有可能出现在程序中的句法位置,它可以合理地应用于声明或类型,或两者兼而有之。

注释是否适用于声明或声明实体的类型 - 因此,注释是声明注释还是类型注释 - 取决于注释类型的适用性:[...]

因此,注释在

void method(String @Annotation ... x) {}

TYPE_USE注解。

和注释

void method(@Annotation String ... x) {}

既是一个TYPE_USE又是一个PARAMETER注解。


您可以验证这一点。

@Target(value = ElementType.TYPE_USE)
@interface Annot {}
public static void method(String @Annot... arg) {}
public static void method2(@Annot String... arg) {}

@Target(value = ElementType.PARAMETER)
@interface Annot {}
public static void method(String @Annot... arg) {} // DOES NOT COMPILE
public static void method2(@Annot String... arg) {}
于 2015-08-11T15:16:56.187 回答
2

当您编写可变参数形式参数时,例如

void method(String... x) {}

然后Java编译器生成一个接受字符串数组的方法;每当您的源代码使用多个参数调用该方法时,Java 编译器都会在调用该方法之前将它们打包到一个数组中。因此,将声明String...视为类似于String[]. 此外,注释的解释相同。

这些注释中的任何一个

void method(String @NonEmpty ... x) {}
void method(String @NonEmpty [] x) {}

适用于数组:类型表示非空字符串数组。注释说明数组或可变参数列表不应为空。您可以使用注释处理器在编译时或运行时强制执行此操作。

这些注释中的任何一个

void method(@English String ... x) {}
void method(@English String [] x) {}

适用于元素类型。注释说明该方法采用英语字符串数组。

于 2015-08-11T16:11:10.243 回答