如何获取数组方括号左侧的注解?IDEA提示异常原因是什么?
问题描述
我遇到了Java注解相关的几个问题,代码如下:
public static @MyNullable1 String @MyNullable2[] array = null; @Test public void test() throws Exception { Annotation[] annotations = getClass().getField("array").getAnnotations(); System.out.println(Arrays.toString(annotations)); }
执行后输出仅为:
[@test.MyNullable1()]
另外,移除@MyNullable2后,IDEA会提示'null' is assigned to a variable that is annotated with @NotNull。
我有三个疑问:
- IDEA为什么会弹出这个提示?
- 如何获取方括号左侧的
@MyNullable2注解? - 这两个位置的注解有什么区别?
以下是MyNullable1和MyNullable2的定义:
@Documented @Nonnull(when = When.MAYBE) @Retention(RetentionPolicy.RUNTIME) @TypeQualifierNickname @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE, }) public @interface MyNullable1 {} @Documented @Nonnull(when = When.MAYBE) @Retention(RetentionPolicy.RUNTIME) @TypeQualifierNickname @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE, }) public @interface MyNullable2 {}
问题解答
1. IDEA提示的原因
IDEA的空值检查基于JSR 305的类型限定规则,会识别类型注解(ElementType.TYPE_USE)。移除@MyNullable2后,数组的元素类型String没有被标记为可空,IDEA默认判定数组元素应为@NotNull。你把null赋值给数组变量时,虽然变量本身被@MyNullable1标记为可空,但IDEA会同时校验数组元素的可空性——它认为数组元素必须非空,而直接赋值null相当于没有初始化元素,因此触发提示。
2. 获取方括号左侧注解的方法
getField().getAnnotations()只能拿到字段本身的注解(也就是@MyNullable1),而@MyNullable2是标注在数组元素类型上的类型注解,属于TypeAnnotation范畴,需要通过Field.getGenericType()结合AnnotatedTypeAPI来获取:
修改测试代码如下:
@Test public void test() throws Exception { Field field = getClass().getField("array"); // 获取字段的带注解类型包装 AnnotatedType annotatedType = field.getAnnotatedType(); if (annotatedType instanceof AnnotatedArrayType) { AnnotatedArrayType annotatedArrayType = (AnnotatedArrayType) annotatedType; // 获取数组元素类型的注解集合 Annotation[] elementAnnotations = annotatedArrayType.getAnnotatedGenericComponentType().getAnnotations(); System.out.println(Arrays.toString(elementAnnotations)); // 输出[@test.MyNullable2()] } // 原字段注解获取逻辑 Annotation[] fieldAnnotations = field.getAnnotations(); System.out.println(Arrays.toString(fieldAnnotations)); // 输出[@test.MyNullable1()] }
这段代码通过AnnotatedArrayType拿到数组元素的注解,就能成功获取@MyNullable2。
3. 两个位置注解的核心区别
@MyNullable1:标注在字段本身上,属于ElementType.FIELD类型注解,描述的是整个数组变量的可空性——意思是这个数组变量本身可以被赋值为null。@MyNullable2:标注在数组的元素类型上,属于ElementType.TYPE_USE类型注解,描述的是数组中每个元素的可空性——意思是数组里的每个元素允许为null。
简单总结:
@MyNullable1 String[]:数组变量可以是null,但数组元素默认非空(无额外注解时)。String @MyNullable2[]:数组变量的可空性由字段注解决定,数组内的元素允许为null。
内容的提问来源于stack exchange,提问作者FredSuvn
相关产品推荐
相关产品推荐

