【问题标题】:Java 14 Language Specification Annotation Element Explanation - Possibly Typo?Java 14 语言规范注释元素说明 - 可能是错字?
【发布时间】:2020-04-15 13:45:35
【问题描述】:

我一直在努力理解 Java 语言规范中的 AnnotationTypeDeclaration。 https://docs.oracle.com/javase/specs/jls/se14/html/jls-9.html#jls-AnnotationTypeElementDeclaration

上面写着:

AnnotationTypeElementDeclaration:
{AnnotationTypeElementModifier} UnannType Identifier ( ) [Dims] [DefaultValue] 

根据这个签名——Dims 表达式可以放在Identifier 和defaultValue 之间,这样写一个注释元素似乎是合法的:

package com.example.demo;

import java.lang.annotation.*;

@interface RequiredValue {
    String value() @Required[] default "default value";
}

@Target({ElementType.TYPE, ElementType.TYPE_USE})
@interface Required {

}

但是,编译器吐出以下错误:

Incompatible types. Found: 'com.example.demo.Required', required: 'java.lang.String @com.example.demo.Required []'

在努力解决这个错误之后,我得到了:

package com.example.demo;

import java.lang.annotation.*;

@interface RequiredValue {
    Required value() @Required[] default @Required;
}

@Target({ElementType.TYPE, ElementType.TYPE_USE})
@interface Required {

}

您很容易注意到,我必须将value() 元素的类型更改为Required。现在代码编译没有错误。

也可以省略defaultValue 定义。

@interface RequiredValue {
    Required value() @Required[] default @Required;
    Required name() @Required[];
}

那么 - 拥有Dims(示例中为@Required[])的意义何在?我还没有看到实际上看起来像上面示例的一行 Java 代码。我的问题只是源于 Java 语言规范和我想更好地了解 Java 语言的好奇心。我可以想到它的几个含义,但语法看起来太奇怪了,无法推理。提前致谢!

【问题讨论】:

  • 这对我来说编译得很好。第一个 sn-p 中的 @Required 注释了额外(数组)维度 []。局部数组变量的等价物是int @Required [] ids; 或常规方法public int method() @Required [](或public int @Required [] method())。反射不允许您访问其中一些,更多用于注释处理器和静态分析工具。
  • @SotiriosDelimanolis 所以,String value() []; 在功能上与String[] value(); 相同?
  • 如果不清楚,您的第一个 sn-p 是一个注释元素,其返回类型为 String[],而不是 String。
  • @VGR 是的,没错。
  • @SotiriosDelimanolis 感谢您的快速回答!请发表您的想法作为答案,以便我接受。点赞还不够;)

标签: java annotations jls


【解决方案1】:

您可以将public int[] sort(int[] arr) 之类的方法标头替换为public int sort(int arr[]) [] 之类的名称。两者是等价的。 Java 有一些奇怪的替代数组语法,因为它希望 C 程序员感到舒适。

编辑:根据@Sotirios Delimanolis 的说法,@Required 注释适用于数组维度,因此它与返回类型为@Required String[] 并不完全相同

所以你的注释是:

@interface RequiredValue {
    //Notice it's an array here              v
    String value() @Required[] default {"default value"};
}

基本上相当于这个:

@interface RequiredValue {
    @Required String[] value() default {"default value"};
}

这只是 Java 的一个怪癖。

【讨论】:

  • 这不太对。根据@Target 的@Required,在您的第二个sn-p 中,注释可能会应用于整个返回类型、方法,而不是数组维度本身,这就是第一个sn-p做。
  • 我明白了。不过,我在 JavaDocs 中没有看到维度 ElementType。它是如何工作的?
  • TYPE_USE 将适用于 iirc。
【解决方案2】:

总而言之,问题源于 Java 语言本身是 C++ 语言的替代品,因此保留了 C 样式的数组语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2014-02-17
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多