Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8173165

javac should reject references to enum constants from nested classes inside instance initializers

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      On CentOS

      java version "1.8.0_112"
      Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

      On OSX, tested both

      java version "1.8.0_91"
      Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

      and

      jopenjdk version "9-internal"
      OpenJDK Runtime Environment (build 9-internal+0-2016-08-03-125324.jsailor.jdk9)
      OpenJDK 64-Bit Server VM (build 9-internal+0-2016-08-03-125324.jsailor.jdk9, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux devbig340.prn1.facebook.com 4.0.9-68_fbk12_4058_gd84fdb3 #1 SMP Fri Aug 26 15:02:40 PDT 2016 x86_64 x86_64 x86_64 GNU/Linux
      CentOS Linux release 7.3.1611 (Core)

      also

      Darwin karkat 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64
      ProductName: Mac OS X
      ProductVersion: 10.12.2
      BuildVersion: 16C67


      A DESCRIPTION OF THE PROBLEM :
      The JLS forbids references to enum constants from within instance variable initializers of the same enum type. However, javac improperly allows such references if they occur inside a nested class in the instance variable initializer. See:


      JLS 8.9.2 https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.2

      It is a compile-time error to reference a static field of an enum type from constructors, instance initializers, or instance variable initializer expressions of the enum type, unless the field is a constant variable (§4.12.4).

      JLS 8.9.3 https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3

      The members of an enum type E are all of the following:

      For each enum constant c declared in the body of the declaration of E, E has an implicitly declared public static final field of type E that has the same name as c. The field has a variable initializer consisting of c, and is annotated by the same annotations as c.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile code below with `javac Main.java`

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      An error from javac along the lines of:


      Main.java:6: error: illegal reference to static field from initializer
              add(FOO);
      1 error

      ACTUAL -
      Code compiles, runs, and prints "[null]"


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
        import java.util.HashSet;
        public class Main {
          public enum Bleh {
            FOO;
            public HashSet<Bleh> vals = new HashSet<Bleh>(){{
              add(FOO);
            }};
          }
          
          public static void main(String[] args) {
            System.out.println(Bleh.FOO.vals);
          }
        }

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

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: