Consider this input:
import java.lang.annotation.*;
public class Test {
Test(Object o) {
Test e = (Test & @Anno Runnable)o;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Anno { }
The @Anno type annotation on "Runnable" in the intersection cast should be noted in the generated class file as a "RuntimeVisibleTypeAnnotations" code attribute, pointing to the corresponding CHECKCAST instruction.
However, the generated attribute points to the CHECKCAST for the "Test" cast, not the "Runnable" cast:
Test(java.lang.Object);
descriptor: (Ljava/lang/Object;)V
flags: (0x0000)
Code:
stack=1, locals=3, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_1
5: checkcast #7 // class java/lang/Runnable
8: checkcast #9 // class Test
11: astore_2
12: return
LineNumberTable:
line 4: 0
line 5: 4
line 6: 12
RuntimeVisibleTypeAnnotations:
0: #15(): CAST, offset=8, type_index=1
Anno
Note the attribute has field "offset=8" but this should instead be "offset=5".
As a side note, the JLS is somewhat unclear when it comes to intersection casts. It just says "The value of the offset item specifies the code array offset of either the bytecode instruction corresponding to the cast expression..." but "cast expression" would really be the whole thing, not the particular type in the cast.
Probably this should be clarified a bit, e.g., it might say "The value of the offset item specifies the code array offset of either the bytecode instruction corresponding to the cast to the specified type in the cast...".
import java.lang.annotation.*;
public class Test {
Test(Object o) {
Test e = (Test & @Anno Runnable)o;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Anno { }
The @Anno type annotation on "Runnable" in the intersection cast should be noted in the generated class file as a "RuntimeVisibleTypeAnnotations" code attribute, pointing to the corresponding CHECKCAST instruction.
However, the generated attribute points to the CHECKCAST for the "Test" cast, not the "Runnable" cast:
Test(java.lang.Object);
descriptor: (Ljava/lang/Object;)V
flags: (0x0000)
Code:
stack=1, locals=3, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_1
5: checkcast #7 // class java/lang/Runnable
8: checkcast #9 // class Test
11: astore_2
12: return
LineNumberTable:
line 4: 0
line 5: 4
line 6: 12
RuntimeVisibleTypeAnnotations:
0: #15(): CAST, offset=8, type_index=1
Anno
Note the attribute has field "offset=8" but this should instead be "offset=5".
As a side note, the JLS is somewhat unclear when it comes to intersection casts. It just says "The value of the offset item specifies the code array offset of either the bytecode instruction corresponding to the cast expression..." but "cast expression" would really be the whole thing, not the particular type in the cast.
Probably this should be clarified a bit, e.g., it might say "The value of the offset item specifies the code array offset of either the bytecode instruction corresponding to the cast to the specified type in the cast...".
- relates to
-
JDK-8371734 Clarification needed in JVMS 4.7.20.1 for RuntimeVisibleTypeAnnotations
-
- Open
-