[type-annos-observers] error: enclosing static nested class cannot be annotated ??

Werner Dietl wdietl at gmail.com
Mon Oct 7 19:30:11 PDT 2013


Hi Alex,

thanks for your comments.


> You're saying that an annotation at the outermost level of the type
> (@Illegal Y.YY.Z) is illegal if the type (Y.YY.Z) has any sub-part (YY)
> which is a static member type.
>
> But in CantAnnotateStaticClass2, with basically the same class nest:
>
> class Top {
>   static class Outer {
>     class Inner {}
>     static class SInner {}
>     interface IInner {}
>   }
>
>   @TB Outer. @TC Inner f1c;
>   @TB Outer. @TC SInner f2c; // err
>   @TB Outer. @TC IInner f3c; // err
> }
>
> you're allowing @TB at the outermost level of f1c's type, even though the
> type Outer.Inner involves a static member type (Outer is static in Top).
>
> Why no error? Can you please try to write a few bullet points for what
> you've made javac do?

I think there is a difference between Srikanth's example and the test case.
The basic intuition I have is that if in the inner class I can write
"Outer.this", then Outer is not only for scoping - that is, I can use
a type annotation on it.

Let's take Srikanth's example and add two fields:

class Y {
        static class YY {
                Object o = Y.this; // illegal

                class Z {
                        Object o = YY.this; // ok
                        Z() {}
                }
        }
}

If I have "Y.YY", Y is the outer type and YY is the nested type.
In YY, writing "Y.this" is forbidden - there is no enclosing instance.
Therefore "@TA Y. YY" should be forbidden, because it applies a type
annotation to a construct only used for scoping.

On the other hand, in YY.Z, we can allow a type annotation on YY:
writing YY.this is legal, that is, there is an enclosing instance.

I applied the same rule in the test case that you quote:

class Top {
  static class Outer {
    class Inner {}
    static class SInner {}
    interface IInner {}
  }

  @TB Outer. @TC Inner f1c;
  @TB Outer. @TC SInner f2c; // err
  @TB Outer. @TC IInner f3c; // err
}

Looking at f1c, In class Inner I can access Outer.this. Therefore I
can annotate Outer.
Neither SInner nor IInner have an outer instance and therefore @TB has
to be forbidden.

Put differently, it makes a difference whether the static class is on
the left or right of the selection. It is OK if the left class is
static; it is not OK for the right type to be static.

I think with a slight variation of the rule, one can argue whether
"new Outer.Inner()" should be legal or not.

Does this make sense? If not, what is the correct interpretation?


> Separately, I can understand the error for @TB at the outermost level of
> f2c's type and f3c's type, since Outer is being used as a scoping mechanism
> to access a static member. That was laid out in Mike's spec:
>
> @Illegal Outer.StaticNestedClass  // illegal!
> @Illegal Outer.staticField        // illegal!

I agree.

cu, WMD.



> On 10/7/2013 8:44 AM, Werner Dietl wrote:
>>
>> Hi Srikanth,
>>
>> I pushed an update to checking of these rules yesterday.
>> Your attached example now passes, as you expected.
>> If you instead try:
>>
>> @Illegal Y.YY.Z z2 = null;
>>
>> you now get:
>>
>> error: scoping construct cannot be annotated with type-use annotation:
>> @Illegal
>>                  @Illegal Y.YY.Z z2 = null;
>>
>> I think this corresponds to what a recent update to the JSR 308 spec
>> prescribes.
>>
>> Comments welcome.
>> cu, WMD.
>>
>>
>>
>> On Mon, Oct 7, 2013 at 2:46 AM, Srikanth S Adayapalam
>> <srikanth_sankaran at in.ibm.com> wrote:
>>>
>>> Hello !
>>>
>>>
>>> I see that 8b108 rejects the following code.
>>> I am trying to trace this behavior back to the
>>> spec - with not clear cut success. Could you
>>> help clarify the behavior ?
>>>
>>> Thanks!
>>> Srikanth.
>>>
>>>
>>>
>>> // --
>>> import java.lang.annotation.ElementType;
>>> import java.lang.annotation.Target;
>>>
>>> @Target(ElementType.TYPE_USE)
>>> @interface Illegal {
>>> }
>>> class Y {
>>>          static class YY {
>>>                  class Z {
>>>                          Z() {}
>>>                  }
>>>          }
>>> }
>>> class X {
>>>          Y.YY.Z foo2() {
>>>                  Y. at Illegal YY.Z z = null;  // illegal ???
>>>                  return z;
>>>          }
>>> }
>>
>>
>>
>>
>



-- 
http://www.google.com/profiles/wdietl


More information about the type-annotations-spec-observers mailing list