简体   繁体   English

Java枚举的奇怪行为

[英]Strange behavior with Java enums

I run into strange behavior with java Enums. 我遇到了Java枚举的奇怪行为。 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. 也许我的问题是愚蠢的,并且在Java规范中有一个答案,但是我还没有找到答案。

If someone understands why java compiler does so, please explain. 如果有人理解为什么Java编译器会这样做,请解释。

Means you are creating an empty enum . 意味着您正在创建一个空的枚举。 An enum by default should have few enumerated values. 默认情况下,枚举应具有少量枚举值。 So the semicolon here is treated as empty enum . 因此这里的分号被视为空枚举。 It is a bad practice to create such enums 创建此类枚举是一个坏习惯

Java enums can have fields and methods as well as regular enum values: Java枚举可以具有字段和方法以及常规枚举值:

enum Color {
  RED,
  GREEN,
  BLUE;

  public static final int C1 = 5;
}

What you're creating by putting the semicolon there is just an enum without any values. 您将分号放在此处创建的只是一个没有任何值的枚举。 Fairly useless, but possible. 毫无用处,但可能。

An enum body must contain the enum constants, and optionally other class components (methods etc.). 枚举主体必须包含枚举常量和可选的其他类组件(方法等)。

See the Java Language Spec section 8.9 参见Java语言规范8.9节

Your first example declares no constants and a public final static field. 您的第一个示例不声明任何常量,并且声明一个公共的final静态字段。 Your second example contains an empty list of constants first (and is counterintuitively valid) 您的第二个示例首先包含一个的常量列表(并且违反直觉地有效)

You can take your second example and add an enum constant eg 您可以举第二个例子并添加一个枚举常量,例如

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

to further demonstrate this. 进一步证明这一点。

As another answer pointed out, the relevant section of the JLS is 8.9, specifically 8.9.1 which states: 另一个答案指出,JLS的相关部分是8.9,特别是8.9.1 ,其中指出:

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 要理解EnumBody定义的含义,必须查看JLS第2.4章,语法表示法 ,其中说

The syntax {x} on the right-hand side of a production denotes zero or more occurrences of x. 产生式右侧的语法{x}表示x的出现次数为零或更多。

Also that 还有那个

The syntax [x] on the right-hand side of a production denotes zero or one occurrences of x. 产生式右侧的语法[x]表示x出现零次或一次。 That is, x is an optional symbol. 也就是说,x是可选符号。 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: [EnumConstantList]并不是那么有趣,因为这是人们期望的:

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). 也就是说,一个或多个EnumConstant用逗号分隔(我不打算使用EnumConstant的定义,我陷入了一个足够深的兔子洞,并且与该问题无关)。

Things get interesting (finally) with the definition of [EnumBodyDeclarations] : 最终[EnumBodyDeclarations]的定义使事情变得有趣[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 . 您错误地指定了EnumBodyDeclarations ,如上面的摘录所示,该EnumBodyDeclarations是非可选的分号,后跟零个或多个ClassBodyDeclaration

This is why your second example is valid 这就是为什么第二个示例有效的原因

It contains the non-optional semicolon followed by a valid ClassBodyDeclaration . 它包含非可选的分号,后跟有效的ClassBodyDeclaration

Phew. ew

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM