spec clarification: type annotations on static nested types

Liam Miller-Cushon cushon at google.com
Wed Feb 21 22:34:20 UTC 2018

I confirmed that the intent of jsr308 matches javac's current behaviour, so
this is a reflection bug. I filed https://bugs.openjdk.
java.net/browse/JDK-8198526 and have a fix out for review:

I'm now reading "nested type" as meaning a type that is nested inside an
*annotatable* type.
i.e. in A.B where B is a non-static inner class, A is an annotatable
enclosing instance type, so a type path is needed to indicate that in
`A. at Foo B` the annotation is on B.
However in A.B where B is a static member class, A is a 'scoping construct'
rather than an annotatable type, so no type path is needed for `A. at Foo B`
since B is the only annotatable type.

Is that reading correct? If it is, I think it would be helpful to clarify
the distinction between nested types and nested classes in the spec.

On Mon, Jan 22, 2018 at 1:30 PM, Liam Miller-Cushon <cushon at google.com>

> I double-checked that the type paths in the class file javac emits are:
>   void f(@A One x) {}
> ...
> type_path_length 1
> type path entry [0]: type_path_kind: 1, type_path_index: 0
>   void g(@A Two x) {}
> ...
> type_path_length 0
> My understanding is still that javac uses type_path_kind=1 to step in to
> (non-static) inner classes, and reflection interprets type_path_kind=1 as
> stepping in to member classes (both non-static and static).
> Is this a javac bug, or a reflection bug, or am I confused?
> Thanks,
> On Mon, Jan 8, 2018 at 2:25 PM, Liam Miller-Cushon <cushon at google.com>
> wrote:
>> Thanks! I have some follow-up questions inline -
>> On Mon, Jan 8, 2018 at 12:42 PM, Alex Buckley <alex.buckley at oracle.com>
>> wrote:
>>> A type annotation can apply to a type that's nested (i.e. deeper) in a
>>> *static* type though. Adapting an example from JLS 9.7.4:
>>> ...
>> In the second case, the nested type which is being annotated is "C . D".
>>> The D part denotes a non-static nested type, yes, but the first type that
>>> we hit when stepping through the path -- C -- is static. The storage of
>>> @Foo thus involves a type_path that descends "deeper in a nested type" --
>>> mentioning anything about static here would be wrong. As a separate issue,
>>> the location where we ultimately find @Foo is, in fact, a non-static member
>>> type, so javap helpfully shows that location as INNER_TYPE:
>> I didn't express what I was thinking, sorry. I agree we're not interested
>> in the static-ness of the outer type.
>> I think javac currently emits type_path_kind=1 steps only when descending
>> in to a member type that is non-static, and that the
>> "location=[INNER_TYPE]" bit of javap's output corresponds directly to the
>> type_path structure in the class file.
>> Is that accurate, and if so is it to spec?
>> My understanding of the `@Foo C . D x;` example was that no type_path is
>> necessary even though C is a member of Test, because C is a static member
>> and Test is 'scoping construct' that is not a valid type annotation target.
>> I don't like how @A has been bounced out of the nested type "T . Two" so
>>> that it allegedly applies to the type of the formal parameter as a whole.
>>> @A actually applies to the type of the static member Two that is declared
>>> by T.
>> Similar to the other example, isn't "@A actually applies to the type of
>> the static member Two" the only interpretation for a type annotation
>> attribute that applies to `T . Two`, since T is a scoping construct and is
>> not a valid type annotation target?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20180221/191f6533/attachment-0001.html>

More information about the compiler-dev mailing list