switch后跟枚举类型,case后列出所有的枚举项,这是一个使用枚举的主流写法,那留着default语句似乎没有任何作用,程序已经列举了所有的可能选项,肯定不会执行到default语句,看上去纯属多余嘛!错了,这个default还是很有用的。以我们定义的日志级别来举例说明,这是一个典型的枚举常量,如下所示:
enum LogLevel{
DEBUG, INFO, WARN, ERROR;
}
一般在使用的时候,会通过swtich语句来决定用户设置的级别,然后输出不同级别的日志,代码如下:
switch(logLevel){
case DEBUG:
……
case INFO:
……
case WARN:
……
case ERROR:
……
}
由于把所有的枚举项都列举完了,不可能有其他值,所以就不需要default代码块了,这是普遍的认识,但问题是我们的switch代码与枚举之间没有强制约束关系,也就是说两者只是在语义上建立了联系,并没有一个强制约束,比如LogLevel枚举发生改变,增加了一个枚举项FATAL,如果此时我们对switch语句不做任何修改,编译虽不会出现问题,但是运行期会发生非预期的错误:FATAL类型的日志没有输出。
为了避免出现这类错误,建议在default后直接抛出一个AssertionError错误,其含义就是“不要跑到这里来,一跑到这里就会出问题”,这样可以保证在增加一个枚举项的情况下,若其他代码未修改,运行期马上就会报错,这样一来就很容易查找到错误,方便立刻排除。
当然也有其他方法解决此问题,比如修改IDE工具,以Eclipse为例,可以把Java→Compiler→Errors/Warnings中的"Enum type constant not covered on' switch'"设置为Error级别,如果不判断所有的枚举项就不能通过编译。