javalanguage-lawyerannotation-processingjls

A @Target-less annotation cannot be applied to a type parameter declaration in Java 19: why not?


Section 9.6.4.1 of the Java Language Specification version 19 lists all declaration contexts in the Java language. One of those declaration contexts is "Type parameter declarations of generic classes, interfaces, methods, and constructors".

The Java Language Specification version 19 says "If an annotation of type java.lang.annotation.Target is not present on the declaration of an annotation interface A, then A is applicable in all declaration contexts and in no type contexts"

The javadocs for @Target in Java 19 say that if I have an annotation class not annotated with @Target, my annotation may be used "as a modifier for any declaration" (full stop).

In the Java Language Specification version 13, but not in 14 and later, the text reads, instead: "If an annotation of type java.lang.annotation.Target is not present on the declaration of an annotation type T, then T is applicable in all declaration contexts except type parameter declarations, and in no type contexts".

The javadocs for @Target in Java 13 (but not in 14 and later) read (similarly): "If an annotation of type java.lang.annotation.Target is not present on the declaration of an annotation type T, then T is applicable in all declaration contexts except type parameter declarations, and in no type contexts".

The javadocs for @Target in Java 17 finally change (belatedly?) to match the specification (as changed in 14), reading (as they do today in Java 19): "If an [sic] @Target meta-annotation is not present on an annotation interface T, then an annotation of type T may be written as a modifier for any declaration".

So given this in Java 19:

@Retention(RetentionPolicy.RUNTIME)
public @interface A {}

public class B<@A C> {}

…I would think it would be legal:

But javac says that @A is not applicable in this type context.

Is this a bug? Or have I misread the Java Language Specification, version 19?


Solution

  • The change to make @Target-less annotations "applicable in all declaration contexts" happened in JDK-8261610.

    I agree with your reading of JLS 19 §9.6.4.1, which says that the 'declaration contexts' include "type parameter declarations of generic classes, interfaces, methods, and constructors", and that

    If an annotation of type java.lang.annotation.Target is not present on the declaration of an annotation interface A, then A is applicable in all declaration contexts and in no type contexts.

    I think this is a bug: https://bugs.openjdk.org/browse/JDK-8303784