昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!”
来看看小王写的代码吧,看完不要骂我装逼啊。
private static String createPlayer(PlayerTypes playerType) {switch (playerType) {
case TENNIS:
return "网球运动员费德勒";
case FOOTBALL:
return "足球运动员C罗";
case BASKETBALL:
return "篮球运动员詹姆斯";
case UNKNOWN:
throw new IllegalArgumentException("未知");
default:
throw new IllegalArgumentException(
"运动员类型: " + playerType);
}
}
看完上述代码后,你是不是会发出这样的感慨——“代码写得很好,没有任何问题啊!”是不是觉得我在无事生非,错怪了小王!但此时我要送上《了不起的盖茨比》中的一句话:
我年纪还轻,阅历不深的时候,我父亲教导过我一句话,我至今还念念不忘。 “每逢你想要批评任何人的时候, ”他对我说,“你就记住,这个世界上所有的人,并不是个个都有过你拥有的那些优越条件。”
哈哈,这句话不光是让你看的,也是给我看的。是时候冷静下来谈谈上述 switch 语句的老土问题了。
看到上图了吧,当不小心删掉 default 语句后,编译器就会报错,提示:“没有返回语句”,为了解决这个问题,我们可以新建一个 player 变量作为返回结果,就像下面这样:
private static String createPlayer(PlayerTypes playerType) {String player = null;
switch (playerType) {
case TENNIS:
player = "网球运动员费德勒";
break;
case FOOTBALL:
player = "足球运动员C罗";
break;
case BASKETBALL:
player = "篮球运动员詹姆斯";
break;
case UNKNOWN:
throw new IllegalArgumentException("未知");
}
return player;
}
当添加了 player 变量后,case 语句中就需要添加上 break 关键字;另外在 switch 语句结束后,返回 player。这时候,编译器并不会提示任何错误,说明 default 语句在这种情况下是可以省略的。
从 JDK 12 开始(本例使用的是 JDK 13),switch 语句升级了,不仅可以像传统的 switch 语句那样作为条件的判断,还可以直接作为一个返回结果。来对小王的代码进行改造,如下所示:
private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {
case TENNIS -> "网球运动员费德勒";
case FOOTBALL -> "足球运动员C罗";
case BASKETBALL -> "篮球运动员詹姆斯";
case UNKNOWN -> throw new IllegalArgumentException("未知");
};
}
够 fashion 吧?不仅 switch 关键字之前加了 return 关键字,case 中还见到了 Lambda 表达式的影子,中划线和箭头替代了冒号,意味着箭头右侧的代码只管执行无须 break。
并且,default 语句变成了可选项,可有可无,不信?你也动手试试。
新的 switch 语句足够的智能化,除了有上述的 3 个优势,还可以对枚举类型的条件进行校验。假如在 PlayerTypes 中增加了新的类型 PINGPANG(乒乓球):
public enum PlayerTypes {TENNIS,
FOOTBALL,
BASKETBALL,
PINGPANG,
UNKNOWN
}
此时编译器会发出以下警告: