-
Bug
-
Resolution: Fixed
-
P3
-
5.0
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();
}
}
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();
}
}
- relates to
-
JDK-4903103 Can't compile subclasses of inner classes
- Closed
-
JDK-6657499 javac 1.6.0 fails to compile class with inner class
- Closed