Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to retrieve the annotation at the left of the square brackets of an array

I am unable to retrieve the annotation at the left of the square brackets of an array:

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));
}

The result is only:

[@test.MyNullable1()]

And, if I remove the @MyNullable2, IDEA reports 'null' is assigned to a variable that is annotated with @NotNull: enter image description here

Why is IDEA reporting this? How can I get the annotation at the left of the square brackets? And what's different in annotations at different positions?

Here are MyNullable1 and 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 {}
like image 706
FredSuvn Avatar asked Dec 06 '25 15:12

FredSuvn


1 Answers

As you have found out, @MyNullable1 annotates the field array, but it also annotates the array's component type, String. On the other hand, @MyNullable2 does not annotate the field array, but it does annotate the type of the field, String[]. This is the effect that the different annotation positions have.

You should use getAnnotatedType to get the annotations on the type. Here is some code that finds both @MyNullable1 (annotating String) and @MyNullable2 (annotating String[]).

var type = getClass().getField("array").getAnnotatedType();
// this prints @mypackage.MyNullable1() java.lang.String @mypackage.MyNullable2()[]
// so both annotations you want are in this
System.out.println(type); //

// this does not print null, showing that MyNullable2 is annotating 'String[]'
System.out.println(type.getAnnotation(MyNullable2.class));

// I *know* the type of the field, so this cast always succeeds.
// You should add an instanceof check if you are working with an unknown field, of course
var arrayComponentType = ((AnnotatedArrayType)type).getAnnotatedGenericComponentType();
// this does not print null, showing that MyNullable1 is annotating the array component type 'String'
System.out.println(arrayComponentType.getAnnotation(MyNullable1.class));
like image 117
Sweeper Avatar answered Dec 08 '25 05:12

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!