[英]Default null value for annotation fields in Java
我正在创建自定义注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {
public Integer index() default null; // Compiler complains here
}
编译器抱怨null
是不允许的。 我不想将索引字段设为原始类型int
因为它没有意义。 有没有办法为注释字段设置默认null
值?
Error 为注释的字段设置默认空值时的答案提到了Class
类型,因此解决方案有效,但不适用于Integer
, Double
等。
您不能使用null
作为默认(或非默认)值。 Java 语言规范(JLS) 明确禁止使用null
。 从JLS 的 §9.6.2 开始:
如果元素的类型与指定的默认值不相称(第9.7 节),则会出现编译时错误。
如果元素类型与元素值不相称,则会出现编译时错误。 当且仅当以下条件之一为真时,元素类型
T
与元素值V
相称:
T
是数组类型E[]
,并且:
- 如果
V
是ConditionalExpression或Annotation ,则V
与E
相称; 或者如果
V
是ElementValueArrayInitializer ,则V
包含的每个元素值都与E
相称。ElementValueArrayInitializer 类似于普通数组初始值设定项(第 10.6 节),除了 ElementValueArrayInitializer 可能在语法上包含注释以及表达式和嵌套初始值设定项。 但是,嵌套初始化器在 ElementValueArrayInitializer 中在语义上不合法,因为它们永远不会与注释类型声明中的数组类型元素相称(不允许嵌套数组类型)。
T
不是数组类型,并且V
的类型与T
赋值兼容(第 5.2 节),并且:
- 如果
T
是原始类型或String
,则V
是常量表达式(第 15.28 节)。- 如果
T
是Class
或Class
的调用(Class
4.5 节),则V
是类文字(第 15.8.2 节)。- 如果
T
是枚举类型(第 8.9 节),则V
是枚举常量(第 8.9.1 节)。V
不为null
。请注意,如果
T
不是数组类型或注释类型,则元素值必须是 ConditionalExpression(第 15.25 节)。 使用 ConditionalExpression 而不是像 Expression 这样的更一般的产生式是一种语法技巧,可以防止将赋值表达式作为元素值。 由于赋值表达式不是常量表达式,因此它不能是原始或String
类型元素的相应元素值。[...]
这是最后一个要点,“ V
is not null
”,这就是编译错误的原因。
如果您想要一个表示“未设置”的默认值,请使用非空标记值。 例如,如果负数永远不是有效值,那么您可以使用任何负数(例如-1
、 Integer.MIN_VALUE
等)作为默认值。 例如:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {
// note the "public" modifier is implicitly added
Integer index() default Integer.MIN_VALUE;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.