Strange Behavior with Java Enums

advertisements

I run into strange behavior with java Enums. If you write next enum:

public enum Test {
   public static final int C1 = 5;
}

You got a compilation error, it is expected because you did not declare enum constants in the beginning.

But the strange part is if you just add a semicolon without a constant name in the beginning:

public enum Test {
   ;
   public static final int C1 = 5;
}

Your code will be compiled successfully.

Maybe my question is dumb and there is an answer in java specification but I have not found one yet.

If someone understands why java compiler does so, please explain.


As another answer pointed out, the relevant section of the JLS is 8.9, specifically 8.9.1 which states:

The body of an enum declaration may contain enum constants. An enum constant defines an instance of the enum type.

EnumBody:
{ [EnumConstantList] [,] [EnumBodyDeclarations] }

To understand the meaning of the EnumBody definition one must look at JLS Chapter 2.4, Grammar Notation, which says

The syntax {x} on the right-hand side of a production denotes zero or more occurrences of x.

Also that

The syntax [x] on the right-hand side of a production denotes zero or one occurrences of x. That is, x is an optional symbol. The alternative which contains the optional symbol actually defines two alternatives: one that omits the optional symbol and one that includes it.

How does this relate to your question? It means valid enum declarations are the following (some grammar notation follows, bear with me):

public enum Test {
}

public enum Test {
  [EnumConstantList]
}

public enum Test {
  [EnumConstantList] ,
}

public enum Test {
 ,
}

public enum Test {
  [EnumBodyDeclarations]
}

public enum Test {
 , [EnumBodyDeclarations]
}

public enum Test {
  [EnumConstantList] [EnumBodyDeclarations]
}

public enum Test {
  [EnumConstantList] , [EnumBodyDeclarations]
}

[EnumConstantList] is not that interesting because it's what one would expect:

EnumConstant {, EnumConstant}

That is, one or more EnumConstant separated by commas (I'm not going into the definition of EnumConstant, I've fallen into a deep enough rabbit hole plus it's not relevant to the question).

Things get interesting (finally) with the definition of [EnumBodyDeclarations]:

EnumBodyDeclarations:
; {ClassBodyDeclaration}

This is why your first example is invalid

You incorrectly specified EnumBodyDeclarations which as the above excerpt shows is a non-optional semicolon followed by zero or more ClassBodyDeclaration.

This is why your second example is valid

It contains the non-optional semicolon followed by a valid ClassBodyDeclaration.

Phew.

This also means the following are valid enum declarations:

public enum Test {
 ;
}

public enum Test {
 ,;
}

public enum Test {
   ,;
   public static final int C1 = 5;
}

public enum Test {
   CAT,
}

public enum Test {
   CAT;
}

public enum Test {
   CAT,;
}

public enum Test {
   CAT,;
   public static final int C1 = 5;
}

public enum Test {
   CAT;
   public static final int C1 = 5;
}

but never

public enum Test {
   CAT,
   public static final int C1 = 5;
}