Вчера утром я удаленно просматривал код двух новых коллег, большая часть кода красиво написана, строга и хорошо прокомментирована, что меня очень устраивает. Но когда я увидел заявление о переключении, написанное одним из них, я не мог не закричать: «Чёрт возьми, Сяо Ван, заявление о переключении, которое вы написали, слишком старомодно!»
Давайте взглянем на код, написанный Сяо Ваном. Не ругайте меня за то, что я притворяюсь после его прочтения.
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 выше.
Посмотрите на картинку выше, когда вы случайно удалите оператор по умолчанию, компилятор сообщит об ошибке, подсказав: «Нет оператора возврата», чтобы решить эту проблему, мы можем создать новую переменную игрока в качестве возвращаемого результата, например следующее:
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 возвращается игрок. В это время компилятор не выдаст никакой ошибки, указывая на то, что оператор по умолчанию в этом случае можно опустить.
Начиная с JDK 12 (в этом примере используется JDK 13), оператор switch был обновлен не только как условное суждение, как традиционный оператор switch, но и как прямой результат возврата. Давайте изменим код Xiao Wang следующим образом:
private static String createPlayer(PlayerTypes playerType) {
return switch (playerType) {
case TENNIS -> "网球运动员费德勒";
case FOOTBALL -> "足球运动员C罗";
case BASKETBALL -> "篮球运动员詹姆斯";
case UNKNOWN -> throw new IllegalArgumentException("未知");
};
}
Это достаточно модно? Не только ключевое слово return добавляется перед ключевым словом switch, но и видно в случаеЛямбда-выраженияТень , тире и стрелка заменяют двоеточие, что означает, что код справа от стрелки просто выполняется без перерыва.
Более того, заявление по умолчанию стало необязательным, необязательным, вы верите в это? Вы тоже попробуйте.
Новый оператор switch достаточно умен, помимо трех вышеперечисленных преимуществ, он также может проверять условия типа перечисления. Если в PlayerTypes добавлен новый тип PINGPANG (шарик для пинг-понга):
public enum PlayerTypes {
TENNIS,
FOOTBALL,
BASKETBALL,
PINGPANG,
UNKNOWN
}
В этот момент компилятор выдает следующее предупреждение:
Это означает, что условие case в переключателе не полностью покрывает возможные значения в перечислении. Хорошо, давайте добавим условие PINGPANG. Взгляните на полный код:
public class OldSwitchDemo {
public enum PlayerTypes {
TENNIS,
FOOTBALL,
BASKETBALL,
PINGPANG,
UNKNOWN
}
public static void main(String[] args) {
System.out.println(createPlayer(PlayerTypes.BASKETBALL));
}
private static String createPlayer(PlayerTypes playerType) {
return switch (playerType) {
case TENNIS -> "网球运动员费德勒";
case FOOTBALL -> "足球运动员C罗";
case BASKETBALL -> "篮球运动员詹姆斯";
case PINGPANG -> "乒乓球运动员马龙";
case UNKNOWN -> throw new IllegalArgumentException("未知");
};
}
}
Оператор switch становится мощным выражением switch, и это здорово! Что, если бы спортсмен мог играть и в баскетбол, и в настольный теннис?
private static String createPlayer(PlayerTypes playerType) {
return switch (playerType) {
case TENNIS -> "网球运动员费德勒";
case FOOTBALL -> "足球运动员C罗";
case BASKETBALL,PINGPANG -> "牛逼运动员沉默王二";
case UNKNOWN -> throw new IllegalArgumentException("未知");
};
}
Как и в приведенном выше коде, просто используйте английскую запятую "," для разделения условий, 666 ах!
Не убежден? Выражения переключения еще более эффективны,->
Правая сторона также может быть{}
Блок кода, заключенный в круглые скобки, как лямбда-выражение.
private static String createPlayer(PlayerTypes playerType) {
return switch (playerType) {
case TENNIS -> {
System.out.println("网球");
yield "网球运动员费德勒";
}
case FOOTBALL -> {
System.out.println("足球");
yield "足球运动员C罗";
}
case BASKETBALL -> {
System.out.println("篮球");
yield "篮球运动员詹姆斯";
}
case PINGPANG -> {
System.out.println("乒乓球");
yield "乒乓球运动员马龙";
}
case UNKNOWN -> throw new IllegalArgumentException("未知");
};
}
Внимательные одноклассники найдут ключевое слово, которое никогда раньше не встречалиyield
, в чем разница между ним и традиционным возвратом и разрывом?
Давайте сначала посмотрим на официальное объяснение:
A yield statement transfers control by causing an enclosing switch expression to produce a specified value.
Это означает, что оператор yield передает управление, заставляя охватывающее его выражение switch возвращать указанное значение. Узнать большеyield
ключевое слово, мы можем декомпилировать байт-код:
private static String createPlayer(NewSwitchDemo3.PlayerTypes playerType) {
String var10000;
switch(playerType) {
case TENNIS:
System.out.println("网球");
var10000 = "网球运动员费德勒";
break;
case FOOTBALL:
System.out.println("足球");
var10000 = "足球运动员C罗";
break;
case BASKETBALL:
System.out.println("篮球");
var10000 = "篮球运动员詹姆斯";
break;
case PINGPANG:
System.out.println("乒乓球");
var10000 = "乒乓球运动员马龙";
break;
case UNKNOWN:
throw new IllegalArgumentException("未知");
default:
throw new IncompatibleClassChangeError();
}
return var10000;
}
Когда компилятор генерирует байт-код,yield
Ключевые слова автоматически экранируются и преобразуются в традиционные операторы break. Это теперь ясно?
Однако, сказав это, те коды, которые кажутся модными, просто передают часть шоу-работы компилятору, и могут быть проблемы несовместимости со старыми версиями и недружественность к тиммейтам - код такой же грязный, как и он. , Это может быть наиболее практичным.
«Извините, я извиняюсь перед вами за то, что вчера утром был высокомерным…» Я отправил Сяо Вану сообщение.
Что ж, мои дорогие читатели и друзья, вышеизложенное и есть все содержание этой статьи, надеюсь завоевать вашу благосклонность. Кстати, у меня есть еще одна маленькая просьба: оригинальность непроста, если сочтете это полезным, пожалуйста, не скупитесь на рукикаксила — потому что это будет самой сильной мотивацией для моего письма.