13

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?

2 Answers 2

13

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.

Sign up to request clarification or add additional context in comments.

Comments

12

The position of the @Annotation relative to the accessModifier does not matter. The annotation is on the method and not on the return type.

I compiled and decompiled this with JD-GUI here are my input and output

INPUT

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

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

OUTPUT

@NotNull
public Class<?> getProviderClass2()
{
  return getClass();
}

@NotNull
public Class<?> getProviderClass1()
{
  return getClass();
}

Comments

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.