[type-annos-observers] Receivers and parameters annotated type question

Joel Borggren-Franck joel.franck at oracle.com
Fri Nov 22 06:27:02 PST 2013


Hi Elena,

This turned out to be a compiler issue:
https://bugs.openjdk.java.net/browse/JDK-8029012

public class A {
  public A() { }

    class B {
        public B(@X A. @Y B param) { }
    }
}

"param" here should return [@Y] from getAnnotatedType().getAnnotations().

The constructor for B..getAnnotatedParameterTypes()[0] will return the
outer.this synthetic/mandated parameter which should not have any
annotations in this case and in this case have type A (and therefor gets
the @X annotation).

HTH

cheers
/Joel

On 2013-11-21, elena votchennikova wrote:
> Hi Joel,
> 
> thank you a lot for taking care about it.
> 
> Is my understanding correct:
> if we have the following definition of the parameter
> @Annot(0) MiniTest. @Annot(1) Inner. @Annot(2) InnerInner param
> 
> then AnnotatedType of the param will has type InnerInner with the
> only one annotation @Annot(2) because other annotations (@Annot(1)
> and @Annot(0)) relate to the Inner and MiniTest types corresponding.
> 
> 
> Thank you,
> Elena
> 
> On 21.11.2013 19:04, Joel Borggren-Franck wrote:
> >Hi Elena,
> >
> >Thanks for the report. This looks like a bug in core reflection.
> >
> >I will file one.
> >
> >cheers
> >/Joel
> >
> >On 2013-11-21, elena votchennikova wrote:
> >>Please take a look at another case.
> >>
> >>I've added constructor with InnerInner annotated parameter in every class.
> >>
> >>-----------------------------------------------------------------------------------------
> >>public class MiniTest {
> >>     public MiniTest(@Annot(2) MiniTest. @Annot(3) Inner. @Annot(4)
> >>InnerInner param) {
> >>     }
> >>
> >>     class Inner {
> >>         public Inner(@Annot(2) MiniTest. @Annot(3) Inner. @Annot(4)
> >>InnerInner param) {
> >>         }
> >>
> >>         class InnerInner {
> >>             public InnerInner(@Annot(2) MiniTest. @Annot(3) Inner.
> >>@Annot(4) InnerInner param) {
> >>             }
> >>         }
> >>     }
> >>...
> >>-----------------------------------------------------------------------------------------
> >>
> >>And the result is strange too:
> >>-----------------------------------------------------------------------------------------
> >>MiniTest constructor1 parameter
> >>- annotations count: 1
> >>   Annot value: 4
> >>Inner constructor1 parameter
> >>- annotations count: 1
> >>   Annot value: 2
> >>InnerInner constructor1 parameter
> >>- annotations count: 1
> >>   Annot value: 3
> >>-----------------------------------------------------------------------------------------
> >>
> >>The full mini-test is attached.
> >>
> >>
> >>Thanks a lot,
> >>Elena
> >>
> >>
> >>On 20.11.2013 16:06, elena votchennikova wrote:
> >>>Hi all,
> >>>
> >>>could you please help me to understand behavior of the following cases.
> >>>
> >>>I get annotations of annotated type via reflection API of the
> >>>following parameter (or receiver with the same annotated type)
> >>>@Annot(2) MiniTest. @Annot(3) Inner parameter
> >>>
> >>>The results are Ok for all cases except one - parameter of the
> >>>constructor of Inner class.
> >>>Please take a look at the example bellow.
> >>>
> >>>The output of the MiniTest run (on the jdk8-b116) will be
> >>>-------------------------------------------------------
> >>>
> >>>MiniTest constructor parameter
> >>>- annotations count: 1
> >>>  Annot value: 3
> >>>Inner constructor parameter
> >>>- annotations count: 1
> >>>  Annot value: 2
> >>>InnerInner constructor receiver
> >>>- annotations count: 1
> >>>  Annot value: 1
> >>>InnerInner constructor parameter
> >>>- annotations count: 1
> >>>  Annot value: 3
> >>>-------------------------------------------------------
> >>>
> >>>Looks like 'Annot value' for the 'Inner constructor parameter'
> >>>case should be 3.
> >>>
> >>>Thank you a lot,
> >>>Elena
> >>>
> >>>
> >>>public class MiniTest {
> >>>
> >>>    public MiniTest(@Annot(2) MiniTest. @Annot(3) Inner param) {
> >>>    }
> >>>
> >>>    class Inner {
> >>>
> >>>        public Inner(@Annot(2) MiniTest. @Annot(3) Inner param) {
> >>>        }
> >>>
> >>>        class InnerInner {
> >>>            public InnerInner(@Annot(0) MiniTest. @Annot(1) Inner
> >>>Inner.this, @Annot(2) MiniTest. @Annot(3) Inner param) {
> >>>            }
> >>>        }
> >>>    }
> >>>
> >>>    public static void main(String[] args) throws NoSuchMethodException {
> >>>        Constructor constructor =
> >>>MiniTest.class.getConstructor(Inner.class);
> >>>        AnnotatedType paramType =
> >>>constructor.getAnnotatedParameterTypes()[0];
> >>>        printInfo(paramType, "MiniTest constructor parameter");
> >>>
> >>>        Constructor innerConstructor =
> >>>Inner.class.getConstructor(MiniTest.class, Inner.class);
> >>>        AnnotatedType innerParamType =
> >>>innerConstructor.getAnnotatedParameterTypes()[0];
> >>>        printInfo(innerParamType, "Inner constructor parameter");
> >>>
> >>>        Constructor innerInnerConstructor =
> >>>Inner.InnerInner.class.getConstructor(Inner.class, Inner.class);
> >>>        AnnotatedType innerInnerReceiverType =
> >>>innerInnerConstructor.getAnnotatedReceiverType();
> >>>        printInfo(innerInnerReceiverType, "InnerInner constructor
> >>>receiver");
> >>>        AnnotatedType innerInnerParamType =
> >>>innerInnerConstructor.getAnnotatedParameterTypes()[0];
> >>>        printInfo(innerInnerParamType, "InnerInner constructor
> >>>parameter");
> >>>    }
> >>>
> >>>    private static void printInfo(AnnotatedType aType, String name) {
> >>>        System.out.println(name);
> >>>        System.out.println("- annotations count: " +
> >>>aType.getAnnotations().length);
> >>>        System.out.println("  Annot value: " + ((Annot)
> >>>aType.getAnnotations()[0]).value());
> >>>    }
> >>>}
> >>>
> >>>@Retention(RetentionPolicy.RUNTIME)
> >>>@Target(ElementType.TYPE_USE)
> >>>@interface Annot {
> >>>    int value();
> >>>}
> >>import java.lang.annotation.*;
> >>import java.lang.reflect.AnnotatedType;
> >>import java.lang.reflect.Constructor;
> >>
> >>public class MiniTest {
> >>
> >>     public MiniTest(@Annot(2) MiniTest. @Annot(3) Inner param) {
> >>     }
> >>
> >>     public MiniTest(@Annot(2) MiniTest. @Annot(3) Inner. @Annot(4) InnerInner param) {
> >>     }
> >>
> >>     class Inner {
> >>
> >>         public Inner(@Annot(2) MiniTest. @Annot(3) Inner param) {
> >>         }
> >>
> >>         public Inner(@Annot(2) MiniTest. @Annot(3) Inner. @Annot(4) InnerInner param) {
> >>         }
> >>
> >>         class InnerInner {
> >>             public InnerInner(@Annot(0) MiniTest. @Annot(1) Inner Inner.this, @Annot(2) MiniTest. @Annot(3) Inner param) {
> >>             }
> >>
> >>             public InnerInner(@Annot(2) MiniTest. @Annot(3) Inner. @Annot(4) InnerInner param) {
> >>             }
> >>         }
> >>     }
> >>
> >>     public static void main(String[] args) throws NoSuchMethodException {
> >>         Constructor constructor = MiniTest.class.getConstructor(Inner.class);
> >>         AnnotatedType paramType = constructor.getAnnotatedParameterTypes()[0];
> >>         printInfo(paramType, "MiniTest constructor parameter");
> >>
> >>         Constructor innerConstructor = Inner.class.getConstructor(MiniTest.class, Inner.class);
> >>         AnnotatedType innerParamType = innerConstructor.getAnnotatedParameterTypes()[0];
> >>         printInfo(innerParamType, "Inner constructor parameter");
> >>
> >>         Constructor innerInnerConstructor = Inner.InnerInner.class.getConstructor(Inner.class, Inner.class);
> >>         AnnotatedType innerInnerReceiverType = innerInnerConstructor.getAnnotatedReceiverType();
> >>         printInfo(innerInnerReceiverType, "InnerInner constructor receiver");
> >>         AnnotatedType innerInnerParamType = innerInnerConstructor.getAnnotatedParameterTypes()[0];
> >>         printInfo(innerInnerParamType, "InnerInner constructor parameter");
> >>
> >>         System.out.println();
> >>
> >>         Constructor constructor1 = MiniTest.class.getConstructor(Inner.InnerInner.class);
> >>         AnnotatedType paramType1 = constructor1.getAnnotatedParameterTypes()[0];
> >>         printInfo(paramType1, "MiniTest constructor1 parameter");
> >>
> >>         Constructor innerConstructor1 = Inner.class.getConstructor(MiniTest.class, Inner.InnerInner.class);
> >>         AnnotatedType innerParamType1 = innerConstructor1.getAnnotatedParameterTypes()[0];
> >>         printInfo(innerParamType1, "Inner constructor1 parameter");
> >>
> >>         Constructor innerInnerConstructor1 = Inner.InnerInner.class.getConstructor(Inner.class, Inner.InnerInner.class);
> >>         AnnotatedType innerInnerParamType1 = innerInnerConstructor1.getAnnotatedParameterTypes()[0];
> >>         printInfo(innerInnerParamType1, "InnerInner constructor1 parameter");
> >>
> >>     }
> >>
> >>     private static void printInfo(AnnotatedType aType, String name) {
> >>         System.out.println(name);
> >>         System.out.println("- annotations count: " + aType.getAnnotations().length);
> >>         System.out.println("  Annot value: " + ((Annot) aType.getAnnotations()[0]).value());
> >>     }
> >>}
> >>
> >>@Retention(RetentionPolicy.RUNTIME)
> >>@Target(ElementType.TYPE_USE)
> >>@interface Annot {
> >>     int value();
> >>}
> 


More information about the type-annotations-spec-observers mailing list