1

我在此处的枚举部分的 Java 语言规范中注意到以下内容:link

switch(this) {
  case PLUS:   return x + y;
  case MINUS:  return x - y;
  case TIMES:  return x * y;
  case DIVIDE: return x / y;
}
throw new AssertionError("Unknown op: " + this);

但是,查看 switch 语句定义部分,我在任何地方都没有注意到这种特殊的语法(相关的 throw 语句)。

我可以在枚举定义之外使用这种“默认情况下抛出异常”语法糖吗?它有什么特别的名字吗?对于缩短“列表中没有的任何内容都会引发异常”的这种行为,这是否被认为是一种好/坏的做法?

4

5 回答 5

3

该教程的作者抛出 AssertionError 感到羞耻 - 为什么不利用 Java 已经为我们提供的异常,例如UnsupportedOperationException

于 2010-05-20T19:52:05.253 回答
2

我不确定我是否理解你,但你似乎相信这是发布的代码示例中语法的throw一部分。switch事实并非如此。switch块和语句是两个独立的东西throw,恰好在这段代码中彼此相邻放置。

更详细地说: all contains statements 中的四个case部分,导致方法中的任何后续指令都被跳过。如果没有任何部分匹配,则继续执行该块之后的行,该行恰好是.switchreturncaseswitchthrow

您可以以非常相似的方式使用throwafter an :if

if (something) {
    return aValue;
}

throw new Exception("Nope");
于 2010-05-20T19:11:18.000 回答
0

有一个default关键词:

switch (whatever) {
  // ...
  default: explode();
}

如果您希望默认情况下抛出异常,那么

  default: throw new Explode();

您的示例仅按其方式工作,因为所有其他分支都从包含函数返回。在我看来,这不是一个很好的编码习惯。

于 2010-05-20T19:11:35.377 回答
0

在 Eclipse 中,如果您没有在 switch 语句中覆盖所有枚举值,它会在编译时生成警告。

但是,如果您提出default:警告不再起作用的情况。default因此,是的,在某些 IDE 中,当所有枚举值都包含在 switch 语句中时,省略大小写的明显优势。

一般来说,如果您的 switch 语句超过 5-6 例,请考虑重新设计代码。通常,人们不理解 Java 中的枚举是完整的类,而枚举值是一等对象,因此在许多情况下,您可以让枚举对象自己完成工作,而不是通过 switch 语句来驱动行为。

在这个特定示例中,枚举可以有一个方法doOp( int x, int y),并且每个枚举成员都可以实现该方法的特定风格。

于 2010-05-20T19:34:13.717 回答
0

正如其他人所说,这不是语法糖。它之所以有效,是因为交换机上的所有分支都从该方法返回。如果将一些其他枚举值放入 switch,则 switch 语句将在不运行任何分支的情况下完成,然后将执行 throw 语句。

switch(this) {
  case PLUS:   return x + y;
  case MINUS:  return x - y;
  case TIMES:  return x * y;
  case DIVIDE: return x / y;
  default: throw new AssertionError("Unknown op: " + this);
}

该代码在功能上是等效的。两者之间的主要区别在于,如果将值添加到 Enum 而不是 switch 语句,则没有默认子句的 switch 将创建编译器警告。

于 2010-05-20T19:34:51.423 回答