Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8044196

Incorrect applying of repeatable annotations with incompatible target to type parameter

    Details

    • Subcomponent:
    • Resolved In Build:
      b63
    • Verification:
      Verified

      Backports

        Description

        Code:
        import java.lang.reflect.*;
        import java.lang.annotation.*;

        @Target({ElementType.TYPE_PARAMETER, ElementType.METHOD})
        @Repeatable(TC.class)
        @interface T { int value(); }

        @Target(ElementType.METHOD)
        @interface TC { T[] value(); }

        public class RepAnno {

            public class C<@T(1) @T(2) N> {}

        }

        Could be compiled without any errors. Note, that TC (container annotation) has target = METHOD.

        JLS declares (9.7.5. Multiple Annotations of the Same Type):
        "If a declaration context or type context has multiple annotations of a repeatable annotation type T, then it is as if the context has no explicitly declared annotations of type T and one implicitly declared annotation of the containing annotation type of T."

        Let's check it with reflection API and extend the code:

        import java.lang.reflect.*;
        import java.lang.annotation.*;

        @Target({ElementType.TYPE_PARAMETER, ElementType.METHOD})
        @Retention(RetentionPolicy.RUNTIME)
        @Repeatable(TC.class)
        @interface T { int value(); }

        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.RUNTIME)
        @interface TC { T[] value(); }

        public class RepAnno {

            public class C1<@T(1) N> {}
            public class C2<@T(1) @T(2) N> {}

            public static void main(String[] args) {

                Class<RepAnno> cl = RepAnno.class;
                Class<?>[] cs = cl.getDeclaredClasses();

                for (Class<?> c : cs) {
                    System.out.println("Class: " + c);
                    TypeVariable<?>[] tvs = c.getTypeParameters();
                    for (TypeVariable<?> tv : tvs) {
                        System.out.println(" T: " + tv.isAnnotationPresent(T.class));
                        System.out.println(" TC: " + tv.isAnnotationPresent(TC.class));
                    }
                }
            }
        }

        It's output is:

        $ java RepAnno
        Class: class RepAnno$C2
            T: false
            TC: true
        Class: class RepAnno$C1
            T: true
            TC: false

        I.e. TC is applied to type parameter of class C2, although TC target (METHOD) should not be applicable to type parameter. Should be an error instead.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  alundblad Andreas Lundblad (Inactive)
                  Reporter:
                  spikalev Sergei Pikalev (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  7 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: