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