带有默认抛出子句的枚举?
我注意到 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该教程的作者抛出 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
我不确定我是否明白你的意思,但你似乎相信
throw
是发布的代码示例中switch
语法的一部分。事实并非如此。switch
块和throw
语句是两个独立的东西,它们恰好在此代码中彼此相邻放置。更详细地说:
switch
中的四个case
部分都包含return
语句,导致跳过该方法中的任何后续指令。如果没有case
部分匹配,则在switch
块后面的行继续执行,这恰好是一个throw
。您可以以非常类似的方式在
if
之后使用throw
:I am not sure if I get you, but you seem to believe that the
throw
is part of theswitch
syntax in the posted code sample. That is not the case. Theswitch
block and thethrow
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 theswitch
all containreturn
statements, causing any subsequent instructions in the method to be skipped. If none of thecase
parts matches, execution continues on the line following theswitch
block, which happens to be athrow
.You could use a
throw
after anif
in a very similar way:有一个
default
关键字:如果您希望默认情况抛出异常,那么
您的示例只能按其方式工作,因为所有其他分支都从包含函数返回。 在我看来,这不是一个很好的编码习惯。
There's a
default
keyword:If you want the default case to throw an exception, then
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.
在 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 omittingdefault
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.正如其他人所说,这不是语法糖。它之所以有效,是因为 switch 上的所有分支都从该方法返回。如果将其他枚举值放入 switch 中,则 switch 语句将完成而不运行任何分支,之后将执行 throw 语句。
该代码在功能上是等效的。两者之间的主要区别在于,如果将值添加到 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.
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.