2012-05-11 104 views
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; 
    } 
    } 
} 

上述代码编译得很好,并给出了预期的输出。枚举参考开关的情况下

我的问题是为什么当创建Color引用'c'时,我们需要通过枚举的名称(即Color.GREEN)来引用它,但在case块中只有枚举值就足够了。它不应该是

case Color.RED: 

etc ???

回答

5

不,它不应该。 Java编译器足够聪明,知道您正在切换Color,因此语言允许使用这种快捷方式(并且正如Paul所说,需要它)。实际上,switch语句的整个编译依赖于编译器知道您正在接通的内容,因为它会根据您指定的枚举值的索引将交换机转换为跳转表。只有在最近你才能够打开非数字的东西,例如String

语言规范的相关部分是JLS Chapter 14.11

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

EnumConstantName: 
    Identifier 

如果你正在寻找了解为什么语言的设计会是这样,那将是很难客观回答。语言设计是微妙的,你必须考虑赋值语法是在添加枚举支持之前几年和几年写的。

+1

+1其实你*有*使用快捷键。请参阅[这篇有趣的文章](http://stackoverflow.com/q/8481635/697449)。 –

+0

@Paul:枚举开关事件标签**必须**是枚举常量的_unqualified_名称。 thnx ...明白了...... – WickeD

2

这是一种语言习惯。许多不同的语言都有枚举,并不是所有的都可以让你这样做。在Java的情况下,由于命名空间,您可以执行Color.RED或其他任何操作。通过这样做,您可以拥有多个具有相同变量名称的枚举,并且不会发生冲突。

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

1

在线路

Color c = Color.GREEN; 

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

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

,而不是简单

ArrayList<String> x = new ArrayList(); 

(这实际上是部分固定在Java 7中,但是那是另一回事。)在switch(...)声明中,种类然而,case是从switch的类型中推断出来的。