Is it possible to put annotations on return Type

I came across this code

@Override
public @NotNull Class<?> getProviderClass() {
    return this.getClass();
}

and I am wondering if it is the same as the code below:

@Override
@NotNull
public Class<?> getProviderClass() {
    return this.getClass();
}

Note: that the @NotNull annotation is in different positions relative to the accessModifier

Is the annotation on the return type in this case or on the method?

Answer

Java 8 allows type annotations, that is, stuff like @Foo int foo = (@Foo int) var;.

The summary of the specification is that it depends on how the @NonNull annotation is declared, specifically how its @Target is specified.

  • If it uses ElementType.TYPE_USE, the annotation applies to the return type.
  • If it uses ElementType.METHOD, it applies to the method declaration.
  • If it uses both (or none), it applies to both the return type and method declaration.

Either way, the annotation is syntactically a modifier of the method, so its position does not matter.

So for example, if @NonNull is declared as a type annotation, then yes, you are asserting that the returned value of the method should not be null.

9.7.4:

It is possible for an annotation to appear at a syntactic location in a program where it could plausibly apply to a declaration, or a type, or both. This can happen in any of the five declaration contexts where modifiers immediately precede the type of the declared entity:

  • Method declarations (including elements of annotation types)

  • Constructor declarations

  • Field declarations (including enum constants)

  • Formal and exception parameter declarations

  • Local variable declarations (including loop variables of for statements and resource variables of try-with-resources statements)

The grammar of the Java programming language unambiguously treats annotations at these locations as modifiers for a declaration, but that is purely a syntactic matter. Whether an annotation applies to a declaration or to the type of the declared entity – and thus, whether the annotation is a declaration annotation or a type annotation – depends on the applicability of the annotation’s type:

  • If the annotation’s type is applicable in the declaration context corresponding to the declaration, and not in type contexts, then the annotation is deemed to apply only to the declaration.

  • If the annotation’s type is applicable in type contexts, and not in the declaration context corresponding to the declaration, then the annotation is deemed to apply only to the type which is closest to the annotation.

  • If the annotation’s type is applicable in the declaration context corresponding to the declaration and in type contexts, then the annotation is deemed to apply to both the declaration and the type which is closest to the annotation.

In the second and third cases above, the type which is closest to the annotation is the type written in source code for the declared entity; if that type is an array type, then the element type is deemed to be closest to the annotation.

Leave a Reply

Your email address will not be published. Required fields are marked *