带有默认抛出子句的枚举?

发布于 2024-09-02 21:03:04 字数 507 浏览 5 评论 0原文

我注意到 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 语句)。

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

I noticed the following in the Java Language spec in the section on enumerations here: 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);

However, looking at the switch statement definition section, I didn't notice this particular syntax (the associated throw statement) anywhere.

Can I use this sort of "default case is throw an exception" syntactic sugar outside of enum definitions? Does it have any special name? Is this considered a good/bad practice for short-cutting this behavior of "anything not in the list throws an exception"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寂寞陪衬 2024-09-09 21:03:04

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

Shame on the writer of that tutorial for throwing an AssertionError - why not make use of the Exceptions that Java provides us already, like UnsupportedOperationException

聚集的泪 2024-09-09 21:03:04

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

更详细地说:switch 中的四个 case 部分都包含 return 语句,导致跳过该方法中的任何后续指令。如果没有 case 部分匹配,则在 switch 块后面的行继续执行,这恰好是一个 throw

您可以以非常类似的方式在 if 之后使用 throw

if (something) {
    return aValue;
}

throw new Exception("Nope");

I am not sure if I get you, but you seem to believe that the throw is part of the switch syntax in the posted code sample. That is not the case. The switch block and the throw statement are two seperate things, which just happens to be placed next to each other in this code.

In more detail: The four case parts in the switch all contain return statements, causing any subsequent instructions in the method to be skipped. If none of the case parts matches, execution continues on the line following the switch block, which happens to be a throw.

You could use a throw after an if in a very similar way:

if (something) {
    return aValue;
}

throw new Exception("Nope");
夜夜流光相皎洁 2024-09-09 21:03:04

有一个 default 关键字:

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

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

  default: throw new Explode();

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

There's a default keyword:

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

If you want the default case to throw an exception, then

  default: throw new Explode();

Your example only works the way it does because all the other branches return from the containing function. In my opinion that's not a very good coding habit to get into.

混吃等死 2024-09-09 21:03:04

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

但是,如果您设置 default: 情况,则警告将不再起作用。所以,是的,在某些 IDE 中,当所有枚举值都包含在 switch 语句中时,省略 default 情况确实有好处。

一般来说,如果 switch 语句的数量超过 5-6 个,请考虑重新设计代码。通常,人们不明白 Java 中的枚举是完整的类,而枚举值是一流的对象,因此在许多情况下,您可以要求枚举对象本身完成工作,而不是通过 switch 语句驱动行为。

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

In eclipse, if you do not cover all enum values in a switch statement it generates a warning at compile time.

If, however, you put a default: case that warning does not work anymore. So, yes in some IDEs there is a definite advantage of omitting default case when all enum values are covered in a switch statement.

In general, if your switch statement grows beyond 5-6 cases, consider redesigning the code. Usually, people do not appreciate that enums in Java are full blown classes and enum values are first-class objects, so instead of driving the behavior through the switch statement in many cases you can ask the enum object to do the work itself.

In this particular example the enum can have a method doOp( int x, int y) and each enum member can implement a particular flavor of this method.

久光 2024-09-09 21:03:04

正如其他人所说,这不是语法糖。它之所以有效,是因为 switch 上的所有分支都从该方法返回。如果将其他枚举值放入 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 语句,则不带 default 子句的 switch 将创建编译器警告。

As others have stated, this is not syntax sugar. It works because all of the branches on the switch return from the method. If some other enum value was put into the switch, the switch statement would complete without running any of the branches, after which the throw statement would execute.

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

That code would be functionally equivalent. The major difference between the two is that your switch with no default clause will create a compiler warning if a value is added to the Enum but not to the switch statement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文