Re: [Java Spec Report] reference to nonstatic type from static context

Eric Blake <[email protected]> Tue, 06 Apr 2004 07:10:30 -0600
Newsgroups gmane.comp.java.spec-report
Message-ID <[email protected]>
If I understand you correctly, then what compilers should enforce is the 
following:

package p;
class A<T> {
   class B {
     T t;
   }
   static class C {
     B b1; // illegal, accessing non-static member B by simple name
     A.B b2; // legal, accesses raw type, so T becomes erasure of Object
     A<String>.B b3; // legal, accesses parameterized type, T=String
     {
        b1.t = ""; // illegal, since b1 was illegal
        b2.t = ""; // legal, t treated as Object
        b3.t = ""; // legal, t treated as String
     }
   }
}

package p;
class D extends A.B { // legal, extends raw type, with T as Object
   D() {
     new A().super(); // necessary to extend an inner class
     t = ""; // legal, treated as Object
   }
}

package p;
import p.A.B;
class E extends B { // legal, extends raw type, with T as Object
   E() {
     new A().super(); // necessary to extend an inner class
     t = ""; // legal, treated as Object
   }
}

package p;
class F extends A<String>.B { // legal, extends parameterized type, T=String
   F() {
     new A<String>.super(); // necessary to extend an inner class
     t = ""; // legal, treated as String
   }
}

This means the requirement in 8.5.2 is still poorly worded - "usage of a 
non-static member" is not defined, that I could see.  Perhaps a good 
interpretation of usage is an unqualified name that denotes a non-static 
member of the enclosing class.

How does this play with imports?  Normal imports can import the simple name of 
a non-static class.  So, in a compilation unit that imported the name of the 
non-static class, does the use of that simple name in the static nested class 
count as the imported name (legal) or the enclosing class's name (illegal)? 
And what about classes in scope because they are declared in the same package? 
  I guess another way to word this question is: Does a non-static member type 
shadow the imported and package-level types otherwise in the scope of another 
static member type in the same enclosing class?

package q;
class B {}

package q;
import p.A;
import q.G.H;
class G {
   class H {}
   class A {}
   class B {}
   static class I {
     A a; // legal? Is this imported p.A, or enclosing q.G.A?
     B b; // legal? Is this accessible q.B, or illegal enclosing q.G.B?
     H h; // legal? Either way, it is attempting to refer to q.G.H
   }
}

Also, in an above example, E imported B to extend it by simple name, but the 
import statement currently requires that A be non-parameterized, so E is 
forced to use the raw version of A.  Do you want to consider allowing the 
import of a parameterized type?

package p;
import p.A<String>.B; // currently illegal, but useful
class J extends B {
   J() {
     new A<String>().super();
     t = ""; // t treated as String
   }
}

And how does static import interact with parameterized static methods?  Is 
there any reason that specifying the parameterization of a static method could 
be useful?

package p;
class K {
   static <T> void m(T t) { return t; }
   static <T> void n(T t) { return t; }
}

package p;
import static p.K.<String>m;
import static p.K.n;
class L {
   {
     m(""); // short for K.<String>m("");
     m(this); // illegal, the only m() in scope expects String
     n(""); // short for K.n(""), deduces to K.<String>n("");
     n(this); // short for K.n(this), deduces to K.<L>n(this);
   }
}

Neal Gafter wrote:
> Roly Perera wrote:
> 
>>At first glance that sounds like a mistake in the JLS.  The constraint
>>should only apply to uses of non-static methods and fields.
>>
>>The rationale I think is that to *name* an inner class one does not need
>>an instance of its enclosing class, although to *construct* one, one
>>does.
> 
> 
> With the advent of generics, this is no longer true.
> 
> 
> class A<T> {
>      class B {
>          T t;
>      }
>      static class C {
>          B b = null;
>          {
>              // what is the type of b.t?
>              b.t = "foo";
>          }
>      }
> }
> 

-- 
Someday, I might put a cute statement here.

Eric Blake             [email protected]



To unsubscribe from this mailing list, send an email to:
[email protected]
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
     http://groups.yahoo.com/group/java-spec-report/

<*> To unsubscribe from this group, send an email to:
     [email protected]

<*> Your use of Yahoo! Groups is subject to:
     http://docs.yahoo.com/info/terms/