JDK-5009484 : Compiler fails to resolve appropriate type for outer member
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: generic
  • Submitted: 2004-03-08
  • Updated: 2006-03-15
  • Resolved: 2006-02-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b73Fixed
Related Reports
Relates :  
Relates :  
Description
I wrote the following little program to understand how innerclass emulation
would perform in presence of generics,
especially how name lookup would resolve access to enclosing field which is
generic.
The offending code is located at #3 (see below).

Inside the anonymous #2, the reference to 't' can only be bound through its
enclosing type: anonymous#1, which inherits
it from X<X>, but unfortunately it is private there, and thus isn't visible
(the type of t in this context is X).

Thus, it has to find it in a further enclosing scope, the one of X<T>,
where t is of type T.
Thus I would expect a compiler error when trying to assign t to x (of type
X), as T cannot be assigned to X.

Curiously, javac tolerates this code, but as expected when running it a
ClassCastException occurs since
t is actually holding a String (from new X<String>("OUTER")).
I believe javac did not enforce type safety, and should have rejected this
code as invalid.

I wonder if your new spec is covering cases about innerclass emulation and
generics, as they can complexify quite
a bit the semantics...


public class X <T> {
   private T t;
   X(T t) {
       this.t = t;
   }
   public static void main(String[] args) {
       new X<String>("OUTER").bar();
   }
   void bar() {
       new X<X>(this) {     // #1
           void run() {
               new Object() {  // #2
                   void run() {
                       X x = t;        // #3 <--- which t is bound ?
                   System.out.println(x);
                   }
               }.run();
           }
       }.run();
   }
}

Comments
SUGGESTED FIX Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=4903103
14-02-2006

EVALUATION While the compiler finds the correct symbol which accesses t through the outer instance, it fails to correctly type check the program. The problem is that the type is checked as a member of the anonymous class, not the actual class through which it is accessed.
01-01-2006

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon mustang
07-09-2004

EVALUATION I believe this is a compiler bug. Your description of the semantics is corrrect. That said, I don't see any relation to generics at the specification level. The interaction between nested types and generics is mercifully limited. ###@###.### 2004-03-07
07-03-2004