3

I have the following simple enum in which I want to declare and use a few constants (as the constructor arguments):

public enum MyEnum {

    A(FOO), B(BAR);

    MyEnum(String foo) {
    }

    static final String FOO = "foo";
    static final String BAR = "bar";
}

However, the compiler gives me the following error:

Error:(3, 7) java: illegal forward reference
Error:(3, 15) java: illegal forward reference

If I try to refactor the original enum in an IDE like Intellij IDEA, it extracts the constructor arguments into constants of an inner class, and the following code compiles ok:

SNIPPET 1:

public enum MyEnum {

    A(Constants.FOO), B(Constants.BAR);

    MyEnum(String foo) {
    }

    private static class Constants {
        public static final String FOO = "foo";
        public static final String BAR = "bar";
    }
}

I also found out that even without an inner constants class, the code compiles ok if the constants are specified using fully classified names:

SNIPPET 2:

public enum MyEnum {

    A(MyEnum.FOO), B(MyEnum.BAR);

    MyEnum(String foo) {
    }

    static final String FOO = "foo";
    static final String BAR = "bar";
}

Questions:

  1. Could anybody please explain why the code in snippet 2 compiles while the original one does not? Is it some linking issue?

  2. When choosing between solutions of snippet 1 and 2, which approach is better (cleaner)? To me, snippet 1 (inner class with constants) looks cleaner, but I'm concerned with an extra cost of an inner class: there's gonna be 20 enums in the app +20 inner classes in that case.

Thanks!

Pshemo
  • 122,468
  • 25
  • 185
  • 269
kiwi
  • 31
  • 3
  • 1
    The answer is probably in [JLS Sec 8.3.3](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.3). – Andy Turner May 31 '16 at 20:27
  • I am surprised that snipped 2 actually works. But if JLS will confirm that is intentional I would probably use this version. – Pshemo May 31 '16 at 20:28
  • @Pshemo I think 2) works because in the section I quote above "Specifically, it is a compile-time error if all of the following are true:"; and then 2 makes "The use is a simple name in either a class variable initializer of C or a static initializer of C;" false. Surprising, but there you go. – Andy Turner May 31 '16 at 20:29
  • @AndyTurner Makes sense... – Pshemo May 31 '16 at 20:34

0 Answers0