25

(note: edited question; the prior intent was not clear)

Consider this code:

public final class Foo
{
    private enum X
    {
        VALUE1, VALUE2
    }

    public static void main(final String... args)
    {
        final X x = X.VALUE1;

        switch (x) {
            case VALUE1:
                System.out.println(1);
                break;
            case VALUE2:
                System.out.println(2);
        }
    }
}

This code works fine.

However, if I replace:

case VALUE1: // or VALUE2

with:

case X.VALUE1: // or X.VALUE2

then the compiler complains:

java: /path/to/Foo.java:whatever: an enum switch case label must be the unqualified name of an enumeration constant

SO suggests an answer with this quote from the JLS:

(One reason for requiring inlining of constants is that switch statements require constants on each case, and no two such constant values may be the same. The compiler checks for duplicate constant values in a switch statement at compile time; the class file format does not do symbolic linkage of case values.)

But this does not satisfy me. As far as I am concerned, VALUE1 and X.VALUE1 are exactly the same. The quoted text does not explain it at all for me.

Where in the JLS is it defined that enum values in switch statements have to be written this way?

Community
  • 1
  • 1
fge
  • 119,121
  • 33
  • 254
  • 329
  • 6
    It's simply the way it is because that's how the Java language spec says it is. What is it about the suggested answer you linked that you find lacking? – Tim S. Jul 20 '13 at 17:41
  • 1
    Simply because as far as I am concerned, `VALUE1` or `X.VALUE1` are both the same constant; I see no reason why I cannot substitute the latter for the former. – fge Jul 20 '13 at 17:44
  • 1
    I suspect it's just simplicity - and after all, *every* case in any specific switch statement will have to be of the same type. Why do you *want* the extra flexibility (which would make the JLS more complicated)? – Jon Skeet Jul 20 '13 at 17:46
  • 1
    Well I suppose that class identifier in X.VALUE1, it is not and cannot be a compiletime constant , which is required by the switch statement, which is what the JLS entry says in a way – Vrashabh Irde Jul 20 '13 at 17:48
  • @JonSkeet it is not that I _want_ the extra flexibility; I just wonder what is the fundamental reason that this construct is forbidden at all. – fge Jul 20 '13 at 17:49
  • Your question is basically, "Why did someone at Sun decide to do this when designing the language?". Short of one of those people being on SO, it is unlikely this question is (authoritatively) answerable here. – Brian Roach Jul 20 '13 at 17:49
  • @BrianRoach well, there is an authoritative answer as per the answer – fge Jul 20 '13 at 17:53
  • 1
    @fge: No, there isn't. The answer says why the compiler is complaining - i.e. it identifies the rule in the JLS - but you were asking for a *reason*, and we can't provide that. If you really only wanted a JLS quote and not a justification, you should have been clearer about that. – Jon Skeet Jul 20 '13 at 17:55
  • @JonSkeet as far as I am concerned, the grammar of the language itself is plenty enough an authoritative answer. The fact is, the suggested answer didn't quote this particular grammar specification, which is what I needed there. – fge Jul 20 '13 at 18:00
  • 3
    @fge: Please be clearer about this in the future then. There's a big difference between "show me where the language spec defines this" and "I don't understand why the language was designed this way" and both Brian and I read your question in the latter spirit. – Jon Skeet Jul 20 '13 at 18:02
  • @fge - Prior to your edit the way I read it is you were asking why the JLS was the way it was, not that you hadn't found the specific section. Post-edit it reads better. – Brian Roach Jul 20 '13 at 18:05
  • @BrianRoach sorry for that... Asking "good" questions can be very complicated when you find yourself unable to express your intents clearly :/ – fge Jul 20 '13 at 18:44

1 Answers1

10

SwitchLabel expects an EnumConstantName, which is defined as the enum constant identifier, which is unqualified:

EnumConstant:
Annotationsopt Identifier Argumentsopt ClassBodyopt

jason
  • 236,483
  • 35
  • 423
  • 525
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Thanks a LOT! I have stumbled upon these two points of the JLS without being able to find the link between them – fge Jul 20 '13 at 17:54