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

elena votchennikova elena.votchennikova at oracle.com
Fri Nov 22 07:10:17 PST 2013


Hi Joel,

On 22.11.2013 18:27, Joel Borggren-Franck wrote:
> 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().
Ok
>
> 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).
Oh, right!


Thank you a lot,
Elena

>
> 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