Type annotations and this-reference (receiver) in methods

Werner Dietl wdietl at gmail.com
Mon Feb 17 11:25:09 PST 2014


Hi André, Alex,

>> 2)
>> If you look into the following code, then I think the Method Reference
>> Type Annotations are missing the INNER path.
>> Focus onto first line testInnerGenericHandles().
>>
>>
>> public class DecTestMethodHandles {
>>
>>      static class Test<S> extends DecTestMethodHandles {
>>
>>          public static <T> void testStatic() {
>>              System.out.println("test");
>>          }
>>
>>          public <T> Test() {
>>              System.out.println("new...");
>>          }
>>
>>          public <T> void test() {
>>              System.out.println("test");
>>          }
>>
>>          void testInnerGenericHandles() {
>>              Runnable r = @Nonnull Test<@Nonnull String>::<@Nonnull
>> Integer> new;
>>              r = @Nonnull Test::<@Nonnull Integer> testStatic;
>>              r = new @Nonnull Test<@Nonnull String>()::<@Nonnull
>> Integer> test;
>>              r = super::<@Nonnull String> testSimpleHandles;
>>          }
>> ...
>>      }
>>
>>
>> You get this attribute in testInnerGenericHandles():
>>
>>      RuntimeVisibleTypeAnnotations:
>>        #34 @org.decojer.cavaj.test.jdk8.Nonnull(
>>          target type = 0x45 CONSTRUCTOR_REFERENCE
>>          offset = 0
>>        )
>>
>> There is no INNER path in this. According to the order how this is
>> encoded in bytecode, this bytecode presents "@Nonnull
>> DecTestMethodHandle.Test::new" and not "DecTestMethodHandle. at Nonnull
>> Test::new" (or shorter "@Nonnull Test::new")
>> Haven't tested it the type argument has same issues.
>>
>> May be I understood the spec wrong here and here isn't a inner type path
>> necessary. It's the same topic like previous thread about INNER pathes.
> 
> This feels pretty close to the known bug in attribute generation for
> annotations on nested types.

I don't think there is a problem here. Take this expanded example:

import java.lang.annotation.*;

class Lambda {

    static class TestS<S> {
        public <T> TestS() {
            System.out.println("newS...");
        }
    }
    class TestI<S> {
        public <T> TestI() {
            System.out.println("newI...");
        }
    }

    void testInnerGenericHandles() {
        Runnable r = @TA TestS<@TB String>::<@TC Integer> new;
        r = @TA TestI<@TB String>::<@TC Integer> new;
    }

    @Target(ElementType.TYPE_USE)
    @interface TA {}
    @Target(ElementType.TYPE_USE)
    @interface TB {}
    @Target(ElementType.TYPE_USE)
    @interface TC {}
}


Method testInnerGenericHandles has the following type annotations:

RuntimeInvisibleTypeAnnotations:
 0: #23(): CONSTRUCTOR_REFERENCE, offset=0
 1: #24(): CONSTRUCTOR_REFERENCE, offset=0, location=[TYPE_ARGUMENT(0)]
 2: #25(): CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT, offset=0, type_index=0
 3: #23(): CONSTRUCTOR_REFERENCE, offset=6, location=[INNER_TYPE]
 4: #24(): CONSTRUCTOR_REFERENCE, offset=6, location=[INNER_TYPE,
TYPE_ARGUMENT(0)]
 5: #25(): CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT, offset=6, type_index=0

Where #23, #24, and #25 correspond to TA, TB, and TC, respectively.
With the static inner class, the outer class is only a scoping construct
and no INNER_TYPE is required in the location path.

Does this sound correct?
cu, WMD.


More information about the type-annotations-dev mailing list