7
enum Color {RED, GREEN, BLUE};
class SwitchEnum
{
  public static void main(String[] args)
  {
    Color c = Color.GREEN;
    switch(c)
    {
      case RED:
        System.out.println("red");
        break;
      case GREEN:
        System.out.println("green");
        break;
      case BLUE:
        System.out.println("blue");
        break;
    }
  }
}

上面的代码编译得很好并给出了预期的输出。

我的问题是为什么在创建颜色引用“c”时,我们需要通过枚举的名称(即 Color.GREEN)来引用它,但在这种情况下,只有枚举值就足够了。不应该是

case Color.RED:

ETC???

4

3 回答 3

5

不,不应该。Java 编译器足够聪明,可以知道您正在打开 a Color,因此该语言允许这种快捷方式(正如 Paul 所说,需要它)。实际上,switch 语句的整个编译过程取决于编译器是否知道您正在打开什么,因为它会根据您指定的枚举值的索引将 switch 转换为跳转表。直到最近你才能够打开非数字的东西,比如String.

语言规范的相关部分在JLS 第 14.11 章中:

...
SwitchLabel:
   case ConstantExpression :
   case EnumConstantName :
   default :

EnumConstantName:
   Identifier

如果你想深入了解为什么语言是这样设计的,那将很难客观地回答。语言设计是微妙的,你必须考虑到赋值语法是在添加枚举支持之前多年写的。

于 2012-05-11T04:11:32.093 回答
2

这是一种语言约定。许多不同的语言都有枚举,并不是所有的语言都让你这样做。在 Java 的情况下,由于命名空间,您可以使用 Color.RED 或其他方式。通过这样做,您可以拥有多个具有相同变量名的枚举,并且它们不会发生冲突。

switch 语句不需要您执行 Color.RED(并允许您简单地声明 RED)的原因是 switch 语句知道它是 Color 类型的枚举,并在该名称空间中查找。

于 2012-05-11T04:12:24.650 回答
1

在行

Color c = Color.GREEN;

Color.必需的,因为 Java 编译器不会Color.GREEN从声明 ( Color c) 中推断分配的表达式 ( ) 的类型。出于同样的原因,您必须编写:

ArrayList<String> x = new ArrayList<String>();

而不仅仅是

ArrayList<String> x = new ArrayList();

(这实际上在 Java 7 中已部分修复,但这是另一回事。)在switch(...)声明中,case从 the 的类型推断出 the 的类型switch

于 2012-05-11T05:25:54.130 回答