spec clarification: type annotations on static nested types
Liam Miller-Cushon
cushon at google.com
Thu Nov 30 19:04:55 UTC 2017
JVMS 9 4.7.20.2-A says that a type_path_kind value of 1 is used to indicate
a type annotation "is deeper in a nested type". I believe this should be
"deeper in a *non-static* nested type". A comment in JDK-8027263 confirms
that type path entries are used for inner classes, but not for static
nested classes.
Example:
```
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
class T {
@Retention(RUNTIME)
@Target(TYPE_USE)
@interface A {}
class One {}
static class Two {}
void f(@A One x) {}
void g(@A Two x) {}
public static void main(String[] args) throws Exception {
debug(T.class.getDeclaredMethod("f",
One.class).getAnnotatedParameterTypes()[0]);
debug(T.class.getDeclaredMethod("g",
Two.class).getAnnotatedParameterTypes()[0]);
}
static void debug(AnnotatedType type) {
System.err.println("type annotations: " +
Arrays.toString(type.getAnnotations()));
System.err.println(
"owner type annotations: "
+ Arrays.toString(type.getAnnotatedOwnerType().getAnnotations()));
}
}
```
Using type_path_kind=1 for inner classes, but not for static member
classes, is consistent with current javac behaviour. In the example, the
type path for the annotation on `@A One` is `[INNER_TYPE]` (One is an inner
class), and the type path for the annotation on `@A Two` is empty (Two is a
static member class):
$ javap -v T
...
void f(T$One);
...
RuntimeVisibleTypeAnnotations:
0: #31(): METHOD_FORMAL_PARAMETER, param_index=0,
location=[INNER_TYPE]
...
void g(T$Two);
...
RuntimeVisibleTypeAnnotations:
0: #31(): METHOD_FORMAL_PARAMETER, param_index=0
Using type_path_kind=1 for inner classes is not consistent with the current
behaviour of core reflection. sun.reflect.annotation.AnnotatedTypeFactory
adjusts type paths in the implementation of getAnnotatedOwnerType() for
AnnotatedType and AnnotatedParameterizedType, and when handling
ParameterizedTypes in nestingForType, without considering whether the
nested type is static. This leads to apparently incorrect results for
getAnnotations(). Note that the type annotations on `@A Two` are reported
as being on both `Two` and its enclosing type `T`:
$ javac T.java && java T.
# `@A One`
type annotations: [@T$A()]
owner type annotations: []
# `@A Two`
type annotations: [@T$A()]
owner type annotations: [@T$A()]
My questions are:
* if my understanding of JVMS 9 4.7.20.2-A is correct, can the spec be
updated to clarify that type_path_kind=1 means "deeper in a non-static
nested type", not "deeper in a nested type"?
* is javac's output for this example correct, and if so is this a bug in
AnnotatedTypeFactory?
Thanks,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20171130/d392b32b/attachment.html>
More information about the compiler-dev
mailing list