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. I do not want to make the index field primitive type int
as it would not make sense. Is there a way to have a default null
value for annotation fields?
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.
You cannot use null
as a default (or non-default) value. Using null
is expressly forbidden by the Java Language Specification (JLS). From §9.6.2 of the JLS :
It is a compile-time error if the type of the element is not commensurate ( §9.7 ) with the default value specified.
And from §9.7.1 of the JLS :
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 valueV
if and only if one of the following is true :
T
is an array typeE[]
, and either:
- If
V
is a ConditionalExpression or an Annotation , thenV
is commensurate withE
; orIf
V
is an ElementValueArrayInitializer , then each element value thatV
contains is commensurate withE
.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. 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).
T
is not an array type, and the type ofV
is assignment compatible (§5.2) withT
, and:
- If
T
is a primitive type orString
, thenV
is a constant expression (§15.28).- If
T
isClass
or an invocation ofClass
(§4.5), thenV
is a class literal (§15.8.2).- If
T
is an enum type (§8.9), thenV
is an enum constant (§8.9.1).V
is notnull
.Note that if
T
is not an array type or an annotation type, the element value must be a 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. Since an assignment expression is not a constant expression, it cannot be a commensurate element value for a primitive orString
-typed element.[...]
It's that last bullet point, " V
is not null
", that's the reason for your compilation error.
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. For example:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {
// note the "public" modifier is implicitly added
Integer index() default Integer.MIN_VALUE;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.