在switch语句中使用枚举类型

4

我们可以在switch语句中使用枚举吗?

public enum Color {
  RED,BLUE,YELLOW


}


 public class Use {
  Color c = Color.BLUE;

  public void test(){
      switch(c){
      case Color.BLUE:

      }
  }
}

我在这里遇到了一些错误。

The enum constant Color.BLUE reference cannot be qualified in a case label  Use.java        line 7  Java Problem

2
你能贴出你正在尝试编译的实际代码吗(复制粘贴)? - Bob Kaufman
@所有人:已经粘贴了实际代码,现在可以提出建议吗? - ako
顺便提一下,您可能不想将枚举命名为java.awt.Color类的相同名称,因为这可能会导致混淆的代码。我会在名称中使用“Color”,但会添加后缀或前缀。 - Hovercraft Full Of Eels
5个回答

11
case COLOR.BLUE:

    }
在上面的代码中,只需将COLOR.BLUE替换为BLUE。

例如:

import java.awt.Color;

class ColorEnum {

    enum Color{BLUE,RED,YELLOW};

    public static void main(String[] args) {
        Color c = Color.BLUE;
        switch(c) {
            case BLUE:
                System.out.println("Blue!");
                break;
            case RED:
                System.out.println("Red!");
                break;
            case YELLOW:
                System.out.println("Yellow!");
                break;
            default:
                System.out.println("Logic error!");
        }
    }
}

@ako: 看一下修改。@Ankit: 我觉得在你的答案上发表我的小例子更好(因为它是基于你的答案),希望你不介意。 - Andrew Thompson

4

写成这样:

public void test(){
  switch(c) {
  case BLUE:

  }
}

在用作case标签时,enum标签不得被限定。在JLS 14.11中的语法如下:
SwitchLabel:
    case ConstantExpression :
    case EnumConstantName :
    default :

EnumConstantName:
    Identifier

请注意,需要一个简单的标识符,而不是由枚举名称限定的标识符。
(我不知道为什么他们设计了这样的语法。可能是为了避免语法上的一些歧义。但无论如何,它就是这样。)

1
为什么要使用switch语句呢?不如让枚举本身持有颜色信息(封装它),从而完成所有的脏活累活。这样做的好处是,如果你改变了枚举,就不必深入到使用它的所有代码中去更改所有的switch语句。例如:
import java.awt.Color;

public enum MyColor {
   RED("Red", Color.red), BLUE("Blue", Color.blue), 
   YELLOW("Yellow", Color.yellow);

   private String text;
   private Color color;
   private MyColor(String text,Color color) {
      this.text = text;
      this.color = color;
   }

   public String getText() {
      return text;
   }

   public Color getColor() {
      return color;
   }

   @Override
   public String toString() {
      return text;
   }
}

这个的使用示例如下:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
class MyColorTest extends JPanel {
   private static final Dimension PREF_SIZE = new Dimension(400, 300);

   public MyColorTest() {
      for (final MyColor myColor : MyColor.values()) {
         add(new JButton(new AbstractAction(myColor.getText()) {
            @Override
            public void actionPerformed(ActionEvent arg0) {
               MyColorTest.this.setBackground(myColor.getColor());
            }
         }));

      }
   }

   @Override
   public Dimension getPreferredSize() {
      return PREF_SIZE;
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("MyColorTest");
      frame.getContentPane().add(new MyColorTest());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }

}

你在说什么?原始问题涉及自定义枚举Color,与awt.Color或将一种枚举转换为另一种枚举无关。 - verdesmarald
1
@veredesmarald:原始问题是关于使用枚举来封装颜色概念的,而Switch是OP试图使用枚举来生成相应的java.awt.Color(如果您检查他的帖子,您会看到这一点)。有时候最好的答案不是OP直接寻找的答案,我认为这是其中之一,但我接受您的意见不同和您的负评。 - Hovercraft Full Of Eels
1
@veredesmarald:我在这里试图宣传的想法是将相关信息封装在一个类或枚举中,从而使代码更少出现错误并更容易调试。另一种选择是将switch语句作为枚举的静态方法,但为什么要这样做,当每个枚举成员可以更简单地保存信息呢? - Hovercraft Full Of Eels
1
@Hovercraft:我刚刚看了原始问题,仍然没有看到任何与awt相关的内容。我认为提到的Color枚举只是一个虚构的例子,用于问“如何切换枚举?”有许多情况下切换枚举是有用和正确的,我认为在假设上述片段中的操作后,试图提供一堆不太相关的信息是没有建设性的。 - verdesmarald
@veredesmarald:你的观点很有道理(评论加1),我接受并同意——我的答案不适用于如何使用枚举开关的一般问题。但是在等待原帖作者澄清之前,我将暂时保留我的回答。如果他的陈述证实了你的担忧,那么我会很乐意删除这个答案。 - Hovercraft Full Of Eels
显示剩余2条评论

0
enum MyEnum{
    A,B,C

    MyEnum(){
        switch(this){
            case A:
                 //....
                 break;
            case B:
                 //....
                 break;
            case C:
                 //....
                 break;
        }
    }
}

0

是的,您可以在 switch 语句中使用枚举,但请确保不要在 case 标签中使用 FQCN(完全限定类名)。


以下内容摘自 "枚举常量引用不能在switch语句的case标签中限定"。

简而言之

当Java switch语句使用枚举参数时,应该只使用未限定名称而不是限定名称的枚举值作为case标签;这样,switch语句将认为所有标签都是指向用作参数的枚举类型。

为什么只能使用未限定名称?

如果允许在case标签中使用限定引用,则没有办法限制标签中使用的枚举类型与switch语句的参数类型相同。

public enum Status {
    REGISTERED,
    TERMINATED
}

public class TestStatus {
    public static String getMessage(Status status) {
        String message;
        switch (status) {
            // case Status.REGISTERED: // line 1
            case REGISTERED: // line 2
                message = "Welcome";
                break;
            default:
                message = "Good bye";
                break;
        }
    return message;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接