Java 12以实验形式提供了switch
表达式以及switch
和break
语句的新形式。 对于可能很少用到的构造,有大量新语法和语义,当然,对于那些困惑者和认证考试问题的作者来说,这是一件了不起的礼物。 如果您喜欢Java难题,并且可能想自己创建一些,请继续阅读。
Java 12表达式开关
Java的12只引入了一个表达切换 -a版本的switch
是一个表达式,而不是一个声明。 这是一个简单的示例:
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };
public static int numLetters(Day day) {return switch (day) {case MONDAY, FRIDAY, SUNDAY -> 6;case TUESDAY -> 7;case THURSDAY, SATURDAY -> 8;default -> 9;};
}
真好。
请注意,这种形式的switch
是一个表达式 。 在这种情况下,它的值是return
语句中的表达式。 您还可以将switch
表达式分配给变量,将其作为方法参数传递,并执行Java中的表达式可以执行的所有其他操作。
该图简要说明了它:
表达 | 声明 | |
双向分支 | ? : | if / else |
多路分支 | switch | switch |
为多向分支表达式指定一个运算符会更加一致吗? 当然可以,但是……插入邪恶的笑声……这样我们就可以做更好的益智游戏!
前进。 试试看。 您在哪里可以使用表达式? 当然在switch
语句中。
switch (switch (...) { case ... -> ...; case ... -> ... }) {case ...: ...; case ...: ...;
}
填写一些有趣的内容...
然后询问结果是什么。 还要选择“它不会编译”。 (这就是答案。请注意表达式switch
的第二个case
分支中缺少的分号。)
此表达式switch
具有显着的功能: 不会掉线 。 您不必在每个case
分支的末尾都放一个break
。
太好了-缺少break
是一个常见错误。 但是对于益智游戏制造商来说,这似乎是倒退了一步。
别失望 我将为您带来好消息。
价值突破
假设您要在分支之一中记录某些内容。
case TUESDAY -> { logger.info("Belgium?"); 7 } // Not legal Java
那是Scala语法。 在Scala中,块是一个表达式,其值是该块的最后一个表达式。 在此示例中,为7。但是Java没有块表达式。
Java 12(其版本号使我们联想到圣诞节的12个夜晚),附带了给拼图制作者的礼物:新的break
声明。 它的目的是从case
分支的一个块中返回一个值:
case TUESDAY -> { logger.info("Belgium?"); break 7; }
顺便说一句, ->
专门用来提醒您lambda表达式。 在lambda表达式中,您有类似的问题。 假设您有一个产生表达式的lambda表达式。
Runnable task = () -> 42;
现在,您想添加一个日志记录调用。 您做的事情很相似:
表达 | 声明 | |
拉姆达 | Runnable r = () -> 42; | Runnable r = () -> { logger.log(...); return 42; }; |
case 分支 | case ... -> 42; | case ... -> { logger.log(...); break 42; } |
顺便说一句,老鹰眼的读者会注意到,该表的一个象限中没有末端分号。 更多益智游戏材料…
这个break
语句确实像return
。 它可以嵌套在另一个块中,然后跳到外面,产生值。
case ... -> { if (n % 2 == 0) break 42; else { logger.log(...); break 21; } }
当然,在loop和switch
语句中, break
含义已经不同。 例如,这是非法的:
case ... -> {for (int i = 0; i < a.length; i++) {if (a[i] == x) break i; // Error}break -1;
}
值break
与return
完全相同,但在内部循环和switch
语句中除外,在此禁止。 继续吧-立即解决这个问题。 你知道你想。
标记的休息时间
早在1995年,Java 1.0就引入了诸如类和接口,垃圾回收和Unicode字符串之类的创新,同时坚持使用C语言语法来编写许多程序员熟悉的控制结构。 除了一个小变化。
在Java中,您可以使用带标签的 break
中断嵌套循环,并到达循环的结尾 ,该循环的开头具有匹配的标签。 像这样:
int i = 0;
int j = 0;
found:
while (i < a.length) {while (j < a[i].length) {if (a[i][j] == x) break found;j++;}i++;
}
// Execution continues here after break found;
您曾经使用此功能吗? 如果没有,请不要担心。 除了认证考试,很少有人参加。
如果您在带有break foo;
的case
有一个循环,该怎么办? ? 这完全取决于。 如果foo
作为封闭循环的标签出现,则您有一个标记的break
。 如果不是,并且foo
是一个变量,则您有一个值break
。 如果你们两个都有呢? 那是语法错误。
继续,做一个令人困惑的事情。 你知道你想。
箭头开关语句
再看一下表达式switch
语法。 你可以说
case MONDAY, FRIDAY, SUNDAY ->
代替
case MONDAY: case FRIDAY: case SUNDAY:
很好-替代方法看起来很奇怪:
case MONDAY -> case FRIDAY -> case SUNDAY -> // Just kidding
表情switch
真是太好了。 没有失败。 无需重复case
。 switch
语句变得令人羡慕。
因此,Java设计师决定变得不错,并允许它参与其中。 您现在可以编写:
switch (day) {case MONDAY, FRIDAY, SUNDAY -> // No repeating of casenumLetters = 6; // No fallthrough after ->case TUESDAY -> { logger.info("Tuesday"); numLetters = 7; } case THURSDAY, SATURDAY -> numLetters = 8; default -> numLetters = 9;
}
顽皮开关表达式
现在该轮到表情switch
。 现在switch
语句有两种形式:顽皮(1970年左右)和nice(2018年)。 如果表情switch
想要调皮,会跌倒怎么办?
这是2 x 2图表的谬误出现的地方:
表达 | 声明 | |
没有失败 |
|
|
跌倒 |
|
|
我们真的需要填写缺失的象限吗?
显然是的。
int numLetters = switch(day) {case MONDAY, FRIDAY, SUNDAY:break 6;case TUESDAY:logger.info("Tuesday");break 7;case THURSDAY:logger.info("Thursday"); // Fallthroughcase SATURDAY:break 8;default:break 9;
};
可以在同一switch
混合case ...:
和case ... ->
吗? 可悲的是没有。 曾经考虑过这一点,但是反益智游戏游说组织了这一天。
您可以为第一个分支执行case MONDAY: case FRIDAY: case SUNDAY:
吗? 您可以为此感到困惑,但是到那时,您的听众可能已经失去了生存的意愿。
为您准备的圣诞节前益智游戏
当我对所有这些进行演讲时,我知道我必须做一个困惑者。 这个开关是调皮的还是不错的? 它有什么作用?
int n = 0;n = switch (n) {case 0:n++;default: {O:while (n > 0) {if (n == 1) break O;n--;}if (n > 0) break n;elsebreak 0;}};
- 语法错误
- 有无限循环
-
n
设置为0 -
n
设为1
翻译自: https://www.javacodegeeks.com/2018/12/give-me-break-make-awesome-puzzlers.html