spec clarification: type annotations on static nested types

Alex Buckley alex.buckley at oracle.com
Wed Feb 21 22:43:27 UTC 2018

On 2/21/2018 2:34 PM, Liam Miller-Cushon wrote:
> 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.

That sounds plausible -- the "scoping construct" concept tunneled itself 
fairly deeply into the JLS -- but I don't especially recall that "nested 
type" in JVMS meant to represent only non-static members. I can 
only suggest more digging on type-annotations-spec-experts, sorry.


> 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
> <mailto:cushon at google.com>> wrote:
>     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 <mailto: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 <mailto: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?

More information about the compiler-dev mailing list