首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java Enums和Switch语句-默认情况?

Java Enums和Switch语句-默认情况?
EN

Stack Overflow用户
提问于 2009-05-13 18:23:52
回答 10查看 37.5K关注 0票数 57

对于建议抛出异常的人:

抛出异常不会给我带来编译时错误,它会给我带来运行时错误。我知道我可以抛出异常,我宁愿在编译期间死掉,也不愿在运行时死掉。

首先,我使用的是eclipse 3.4。

我有一个数据模型,它的mode属性是一个Enum。

代码语言:javascript
复制
enum Mode {on(...), off(...), standby(...); ...}

我目前正在编写这个模型的视图,我有代码

代码语言:javascript
复制
...
switch(model.getMode()) {
case on:
   return getOnColor();
case off:
   return getOffColor();
case standby:
   return getStandbyColor();
}
...

我得到了一个错误“这个方法必须返回一个java.awt.Color类型的结果”,因为我没有默认的情况,并且在函数的末尾没有返回xxx。I want 如果有人向枚举中添加了另一个类型(例如shuttingdown),则会出现编译错误,因此我不想设置抛出AssertionError的默认情况,因为这将以修改模式进行编译,直到运行时才会被视为错误。

我的问题是:

为什么EclipseBuilder (和javac)没有意识到这个开关涵盖了所有可能性(或者它涵盖了所有可能性?)不要再警告我需要一个返回类型。有没有办法在不向Mode添加方法的情况下做我想做的事情?

如果做不到这一点,是否可以对没有涵盖Enum所有可能值的switch语句进行警告/错误?

编辑: Rob:这是一个编译错误。我刚刚尝试用javac编译它,但我得到了一个针对该方法的最后一个}的“缺少返回语句”错误。Eclispe只是将错误放在方法的顶部。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2009-05-13 18:55:36

您可以始终使用带有访问者的枚举模式:

代码语言:javascript
复制
enum Mode {
  on {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOn();
      }
  },
  off {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOff();
      }
  },
  standby {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitStandby();
      }
  }

  public abstract <E> E accept( ModeVisitor<E> visitor );

  public interface ModeVisitor<E> {
      E visitOn();
      E visitOff();
      E visitStandby();
  }
}

然后,您将实现类似于以下内容:

代码语言:javascript
复制
public final class ModeColorVisitor implements ModeVisitor<Color> {
    public Color visitOn() {
       return getOnColor();
    }

    public Color visitOff() {
       return getOffColor();
    }

    public Color visitStandby() {
       return getStandbyColor();
    }

}

您可以按如下方式使用它:

代码语言:javascript
复制
return model.getMode().accept( new ModeColorVisitor() );

这要冗长得多,但是如果声明了一个新的枚举,就会立即得到一个编译错误。

票数 71
EN

Stack Overflow用户

发布于 2009-05-13 18:54:31

您必须在Eclipse (window ->首选项)中启用“枚举类型常量未包含在开关中”的设置,并设置错误级别。

在方法的末尾抛出一个异常,但不要使用默认大小写。

代码语言:javascript
复制
public String method(Foo foo)
  switch(foo) {
  case x: return "x";
  case y: return "y";
  }

  throw new IllegalArgumentException();
}

现在,如果有人后来添加了新的案例,Eclipse会让他知道他遗漏了一个案例。所以不要使用默认,除非你有很好的理由这样做。

票数 56
EN

Stack Overflow用户

发布于 2009-05-13 18:49:24

我不知道为什么会出现这个错误,但这里有一个建议,为什么不在枚举本身中定义颜色呢?这样你就不会意外忘记定义新的颜色了。

例如:

代码语言:javascript
复制
import java.awt.Color;

public class Test {

    enum Mode 
    {
        on (Color.BLACK), 
        off (Color.RED),
        standby (Color.GREEN);

        private final Color color; 
        Mode (Color aColor) { color = aColor; }
        Color getColor() { return color; }
    }

    class Model
    {
        private Mode mode;
        public Mode getMode () { return mode; }
    }

    private Model model;

    public Color getColor()
    {
        return model.getMode().getColor();
    }   
}

顺便说一句,为了比较,这里是原始的情况,有编译器错误。

代码语言:javascript
复制
import java.awt.Color;
public class Test {

    enum Mode {on, off, standby;}

    class Model
    {
        private Mode mode;
        public Mode getMode () { return mode; }
    }

    private Model model;

    public Color getColor()
    {
        switch(model.getMode()) {
        case on:
           return Color.BLACK;
        case off:
           return Color.RED;
        case standby:
           return Color.GREEN;
        }
    }   
}
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/859563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档