简体   繁体   English

Java 中注释字段的默认空值

[英]Default null value for annotation fields in Java

I am creating a custom annotation我正在创建自定义注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {

    public Integer index() default null; // Compiler complains here

}

The compiler complains that null is not allowed.编译器抱怨null是不允许的。 I do not want to make the index field primitive type int as it would not make sense.我不想将索引字段设为原始类型int因为它没有意义。 Is there a way to have a default null value for annotation fields?有没有办法为注释字段设置默认null值?

The answer at Error setting a default null value for an annotation's field mention about Class type so the solutions work, but not for Integer , Double etc. Error 为注释的字段设置默认空值时的答案提到了Class类型,因此解决方案有效,但不适用于IntegerDouble等。

You cannot use null as a default (or non-default) value.您不能使用null作为默认(或非默认)值。 Using null is expressly forbidden by the Java Language Specification (JLS). Java 语言规范(JLS) 明确禁止使用null From §9.6.2 of the JLS :JLS 的 §9.6.2 开始

It is a compile-time error if the type of the element is not commensurate ( §9.7 ) with the default value specified.如果元素的类型与指定的默认值不相称(第9.7 节),则会出现编译时错误。

And from §9.7.1 of the JLS :JLS 的 §9.7.1 开始

It is a compile-time error if the element type is not commensurate with the element value.如果元素类型与元素值不相称,则会出现编译时错误。 An element type T is commensurate with an element value V if and only if one of the following is true :当且仅当以下条件之一为真时,元素类型T与元素值V相称

  • T is an array type E[] , and either: T是数组类型E[] ,并且:

    • If V is a ConditionalExpression or an Annotation , then V is commensurate with E ;如果VConditionalExpressionAnnotation ,则VE相称; or或者
    • If V is an ElementValueArrayInitializer , then each element value that V contains is commensurate with E .如果VElementValueArrayInitializer ,则V包含的每个元素值都与E相称。

      An ElementValueArrayInitializer is similar to a normal array initializer (§10.6), except that an ElementValueArrayInitializer may syntactically contain annotations as well as expressions and nested initializers. ElementValueArrayInitializer 类似于普通数组初始值设定项(第 10.6 节),除了 ElementValueArrayInitializer 可能在语法上包含注释以及表达式和嵌套初始值设定项。 However, nested initializers are not semantically legal in an ElementValueArrayInitializer because they are never commensurate with array-typed elements in annotation type declarations (nested array types not permitted).但是,嵌套初始化器在 ElementValueArrayInitializer 中在语义上不合法,因为它们永远不会与注释类型声明中的数组类型元素相称(不允许嵌套数组类型)。

  • T is not an array type, and the type of V is assignment compatible (§5.2) with T , and: T不是数组类型,并且V的类型与T赋值兼容(第 5.2 节),并且:

    • If T is a primitive type or String , then V is a constant expression (§15.28).如果T是原始类型或String ,则V是常量表达式(第 15.28 节)。
    • If T is Class or an invocation of Class (§4.5), then V is a class literal (§15.8.2).如果TClassClass的调用( Class 4.5 节),则V是类文字(第 15.8.2 节)。
    • If T is an enum type (§8.9), then V is an enum constant (§8.9.1).如果T是枚举类型(第 8.9 节),则V是枚举常量(第 8.9.1 节)。
    • V is not null . V不为null

Note that if T is not an array type or an annotation type, the element value must be a ConditionalExpression (§15.25).请注意,如果T不是数组类型或注释类型,则元素值必须是 ConditionalExpression(第 15.25 节)。 The use of ConditionalExpression rather than a more general production like Expression is a syntactic trick to prevent assignment expressions as element values.使用 ConditionalExpression 而不是像 Expression 这样的更一般的产生式是一种语法技巧,可以防止将赋值表达式作为元素值。 Since an assignment expression is not a constant expression, it cannot be a commensurate element value for a primitive or String -typed element.由于赋值表达式不是常量表达式,因此它不能是原始或String类型元素的相应元素值。

[...] [...]

It's that last bullet point, " V is not null ", that's the reason for your compilation error.这是最后一个要点,“ V is not null ”,这就是编译错误的原因。

If you want a default value that means "not set" then use a non-null sentinel value.如果您想要一个表示“未设置”的默认值,请使用非空标记值。 For instance, if a negative number is never a valid value then you can use any negative number (eg -1 , Integer.MIN_VALUE , etc.) as a default value.例如,如果负数永远不是有效值,那么您可以使用任何负数(例如-1Integer.MIN_VALUE等)作为默认值。 For example:例如:

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM