int daysInMonth; switch (month) { case Calendar.JANUARY: case Calendar.MARCH: case Calendar.MAY: case Calendar.JULY: case Calendar.AUGUST: case Calendar.OCTOBER: case Calendar.DECEMBER: daysInMonth = 31; break; case Calendar.APRIL: case Calendar.JUNE: case Calendar.SEPTEMBER: case Calendar.NOVEMBER: daysInMonth = 30; break; case Calendar.FEBRUARY: if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) { daysInMonth = 29; } else { daysInMonth = 28; } break; default: thrownewRuntimeException("Calendar in JDK does not work"); }
System.out.println("There are " + daysInMonth + " days in this month."); } }
容易犯错 1 - break 关键字的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int daysInMonth; switch (month) { case Calendar.JANUARY: case Calendar.MARCH: case Calendar.MAY: break; // WRONG BREAK!!! case Calendar.JULY: case Calendar.AUGUST: case Calendar.OCTOBER: case Calendar.DECEMBER: daysInMonth = 31; break; // snipped }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int daysInMonth; switch (month) { // snipped case Calendar.APRIL: case Calendar.JUNE: case Calendar.SEPTEMBER: case Calendar.NOVEMBER: daysInMonth = 30; // WRONG, NO BREAK!!! case Calendar.FEBRUARY: if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) { daysInMonth = 29; } else { daysInMonth = 28; } break; // snipped }
break 语句的遗漏或者冗余 - 常见软件安全漏洞
凡是使用 switch 语句的代码,都可能成为黑客们重点关注的对象
编写代码和阅读代码要十分小心 - 增加维护成本,降低生产效率
switch 语句需要 break 的原因 - 在不同的情况下,共享部分或者全部的代码片段
这是一个弊大于利的设计
新设计的现代语言 - 更多的使用 switch 语句,但不要使用 break
真实需求依然存在 - 不同场景共享代码片段
容易犯错 2 - 反复出现的赋值语句
1 2 3 4 5 6 7 8 9 10 11
intdaysInMonth=0; switch (month) { // snipped case Calendar.APRIL: case Calendar.JUNE: case Calendar.SEPTEMBER: case Calendar.NOVEMBER: break; // WRONG, INITIAL daysInMonth value IS USED!!! case Calendar.FEBRUARY: // snipped }
daysInMonth 的变量声明和实际赋值是分开的,赋值语句需要反复出现,以适应不同的场景
如果在 switch 语句里,daysInMonth 变量没有被赋值
编译器也不会报错,缺省的或者初始的变量就会被使用
1 2 3 4 5 6 7 8 9 10 11
intdaysInMonth=0; switch (month) { // snipped case Calendar.APRIL: case Calendar.JUNE: case Calendar.SEPTEMBER: case Calendar.NOVEMBER: break; // WRONG, INITIAL daysInMonth value IS USED!!! case Calendar.FEBRUARY: // snipped }
intdaysInMonth=switch (month) { case Calendar.JANUARY, // snipped Calendar.DECEMBER -> 31; case Calendar.APRIL, // snipped Calendar.NOVEMBER -> 30; case Calendar.FEBRUARY -> { // snipped } // WRONG to comment out the default branch, 'switch' expression // MUST cover all possible input values. // // default -> throw new RuntimeException( // "Calendar in JDK does not work"); };