默认情况下Java Enums和Switch语句 ?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

对于提示抛出异常的人: 抛出异常不会给我一个编译时错误,它给我一个运行时错误。我知道我可以抛出异常,我宁愿在编译期间死于运行时。

首先,我使用的是Eclipse 3.4。

我有一个数据模型,它有一个模式属性是一个枚举。

enum Mode {on(...), off(...), standby(...); ...}

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

...
switch(model.getMode()) {
case on:
   return getOnColor();
case off:
   return getOffColor();
case standby:
   return getStandbyColor();
}
...

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

我的问题是: 为什么EclipseBuilder(和javac)不认识到这个开关覆盖了所有的可能性(或覆盖了它们?),并停止警告我需要返回类型。有没有一种方法可以在不向Mode添加方法的情况下做我想做的事情?

如果没有,那么是否有一个选项可以在不包含所有Enum可能值的switch语句上发出警告/错误?

提问于
用户回答回答于

可以始终使用Enum With Visitor模式:

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

然后实现如下内容:

public final class ModeColorVisitor implements ModeVisitor<Color> {
    public Color visitOn() {
       return getOnColor();
    }

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

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

}

可以使用它如下:

return model.getMode().accept( new ModeColorVisitor() );

这要详细得多,但是如果声明了一个新枚举,将立即得到一个编译错误。

用户回答回答于

必须在Eclipse(Window->Preferences)设置中启用错误级别的“Enum类型常量,开关中没有覆盖”。

在方法末尾抛出异常,但不要使用默认情况。

public String method(Foo foo)
  switch(foo) {
  case x: return "x";
  case y: return "y";
  }

  throw new IllegalArgumentException();
}

现在,如果稍后有人添加了新的情况,Eclipse会让他知道他缺少一个案例。因此,除非你有充分的理由这样做,否则永远不要使用默认。

扫码关注云+社区