Name: tb29552 Date: 12/15/2000
/*
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
Javac 1.3 refuses to compile this valid file, with some rather cryptic error
messages:
*/
class A {
class B {
}
public static void main(String[] args) {
new A(){}.new B(){};
}
}
/*
A.java:4: cannot resolve symbol
symbol: class B
new A(){}.new B(){};
^
A.java:4: (<anonymous <any>>) in cannot be applied to (<anonymous A>)
new A(){}.new B(){};
^
2 errors
Quoting from JLS 15.9.1,
"Otherwise, the class instance creation expression is a qualified class instance
creation expression. Let T be the name of the Identifier after the new token. It
is a compile-time error if T is not the simple name (?6.2) of an accessible
(?6.6) non-final inner class (?8.1.2) that is a member of the compile-time type
of the Primary. It is also a compile-time error if T is ambiguous (?8.5). An
anonymous direct subclass of the class named by T is declared. The body of the
subclass is the ClassBody given in the class instance creation expression. The
class being instantiated is the anonymous subclass."
In my example, the first instance creation expression generates <anonymous A>
extends A. This instance inherits the accessible inner class A.B. The second
instance creation has B as the simple name T of the specs, the compile-time
type <anonymous A> for the Primary. Sure enough, there is an accessible,
non-final member B in the type of the primary, since <anonymous A>.B is an alias
for the canonical name A.B. Therefore, the expression should generate the class
<anonymous A>.<anonymous B> extends A.B.
The related sequence,
new A(){}.new B();
compiles, demonstrating that the type <anonymous A>.B is accessible.
In a similar manner, this class also fails, while making the second instance
creation non-anonymous compiles:
class C {
public static void main(String[] args) {
new C(){
class D {}
}.new D(){};
}
}
Here, the first creation expression creates <anonymous C> extends C, and its
inner class <anonymous C>.D. The second expression refers to the simple name D
inside the compile-time type <anonymous C>, which exists. The result should
thus be <anonymous C>.<anonymous D> extends <anonymous C>.D.
*/
(Review ID: 113551)
======================================================================