JDK-6509042 : javac rejects class literals in enum constructors
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2007-01-03
  • Updated: 2011-05-18
  • Resolved: 2011-05-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 JDK 7 Other
6u10Fixed 7 b26Fixed OpenJDK6Fixed
Description
FULL PRODUCT VERSION :
JDK6 release

ADDITIONAL OS VERSION INFORMATION :
All platforms

EXTRA RELEVANT SYSTEM CONFIGURATION :
All configurations

A DESCRIPTION OF THE PROBLEM :
The following code should compile without error, and did compile without error until very late in the JDK6 candidates

frog:~/tmp$ cat -n F.java
     1  enum Foo {
     2    A, B;
     3    Foo() {
     4      Object x = Foo.class;
     5    }
     6  }
frog:~/tmp$ /usr/local/jdk6/bin/java -version
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b104, mixed mode, sharing)
frog:~/tmp$ /usr/local/jdk6/bin/javac F.java
F.java:4: illegal reference to static field from initializer
    Object x = Foo.class;
                  ^
1 error
frog:~/tmp$


REGRESSION.  Last worked in version mustang

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See description

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Code should compile without error.
ACTUAL -
javac rejects the code, as shown in the description.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
F.java:4: illegal reference to static field from initializer

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
enum Foo {
  A, B;
  Foo() {
    Object x = Foo.class;
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use Class.forName instead of a class literal. Unfortunately, the result of Class.forName doesn't have the same generic type as the class literal.

Comments
SUGGESTED FIX see http://sa.sfbay.sun.com/projects/langtools_data/7/6509042
18-12-2007

EVALUATION JLS (8.9) say that "It is a compile-time error to reference a static field of an enum type that is not a compile-time constant from constructors, instance initializer blocks, or instance variable initializer expressions of that type". During the attribution phase, class literals are handled by javac in the same way as static fields. This means that javac assumes that there is a static field names "class" within another class (Foo in the example above). The compiler reports an error since it sees a static field being accessed within an enum constructor; however, since there's no true field access here, the compiler should not reject this code. This problem can be avoided by not applying the checks described in JLS 8.9 to those static fields whose name is "class". *** (#1 of 1): [ UNSAVED ] ###@###.###
17-12-2007