提高你的Java代码质量吧:小心switch带来的空值异常
一、分析
使用枚举定义常量时,会有伴有大量的switch语句判断,目的是为每个枚举解释其行为。
我们知道,目前的Java的switch语句只能判断byte、short、char、int类型(JDK7已经允许使用string类型),为什么枚举也能跟在switch后面呢?很简单,因为编译的时候,编译器判断出switch后面的参数是枚举类型,然后就会根据枚举的排序值继续匹配。如下:
public static void doSports(Season season){
switch(season.ordinal()){
case Season.Spring.ordinal():
…...
case Season.Summer.ordinal():
…...
}
}
看明白了吧,switch语句先计算season变量的排序值,然后与枚举常量的每个排序值进行对比。
二、场景
看这样一个例子:
public static void doSports(Season season){
switch(season){
case Spring:
System.out.printf("春天放风筝");
break;
case Summer:
System.out.println("夏天游泳");
break;
case Autum:
System.out.println("秋天捉知了");
break;
case Winter:
System.out.println("冬天滑冰");
break;
default:
System.out.println("输入错误");
break;
}
}
这段代码有没有问题?我们先来看看如何被调用的,因为传递的是Season类型,也就是一个实例(枚举的本质就是类)对象,那就当然允许为null了,我们就传递一个null进去看看,代码如下:
public static void main(string[] args){
doSports(null);
}
似乎应该打印,“输入错误!",因为在switch中没有匹配,输出default代码块。然而,我们看看真实结果:
Exception in thread "main" java.lang.NullPointerException
at Client.doSports(Client.java:9)
at Client.main(Client.java:5)
怎么会是空指针异常呢?这就与枚举和switch的特性有关了,此问题也在开发中经常发生的。根据上面分析,如果season为null,无法执行ordinal方法,于是报空指针异常了。
三、建议
问题清楚了,建议在switch语句枚举前加入参数是否为null。
提高你的Java代码质量吧:小心switch带来的空值异常的更多相关文章
- [改善Java代码]小心switch带来的空值异常
使用枚举定义常量时,会伴有大量的switch语句判断,目的是伪类每个枚举项解释其行为,例如: public class Client { public static void main(String[ ...
- 提高你的Java代码质量吧:少用静态导入
一.分析 从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...
- 提高你的Java代码质量吧:推荐在复杂字符串操作中使用正则表达式
一.分析 字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...
- 提高你的Java代码质量吧:如果有必要,使用变长数组吧
一.分析 Java中的数组是定长的,一旦经过初始化声明就不可改变长度,这在实际使用中非常不方便. 二.场景 比如要对班级学生的信息进行统计,因为我们不知道一个班级会有多少学生(随时都有可能会有学生 ...
- 提高你的Java代码质量吧:使用valueof前必须进行校验
一.分析 每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode.name.valueOf等,其中valueOf方法会把一个String类型的名称转变成枚 ...
- 提高你的Java代码质量吧:不要让类型默默转换
一.分析 在Java运算中的类型转换,是先运算在进行类型转换的.具体场景如下. 二.场景 在如下程序中: public class Client{ public static final int ...
- 提高你的Java代码质量吧:谨慎包装类型的比较
一.分析 基本类型可以比较大小,其所对应的包装类型都实现了Comparable接口此问题. 二.场景 代码如下: public class Client{ public static void m ...
- 提高你的Java代码质量吧:让我们疑惑的字符串拼接方式的选择
一.分析 对于一个字符串进行拼接有三种方法:加号.concat方法.及StringBuiler或StringBuffer. 1."+"方法拼接字符串 str += " ...
- 提高你的Java代码质量吧:使用构造函数协助描述枚举项
一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性. 二.场景 比如,可以通过枚举构造函数声明业务值,定 ...
随机推荐
- gitlab升级方法
gitlab升级方法:国内网络环境推荐方法二方法一:官网的升级方式 (1)停止git服务 gitlab-ctl stop unicorn gitlab-ctl stop sidekiq gitlab- ...
- 2. QT窗体间值的传递
一.主窗体与子窗体传参 方法有很多,这里介绍一种通过重载子窗体的构造函数实现主窗体参数传入到子窗体,并通过QT信号和槽的机制实现子窗口到主窗口值的传递. 主和子窗体的设置如下: 主要实现功能为: 1 ...
- 关于js中select的简单操作,以及js前台计算,span简单操作
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- java 中Date的格式化样式
public static void main(String[] args) { Date d = new Date(); System.out.println(d); // Date类的默认格式 T ...
- [IDEA学习笔记][keymap]
一个总站: http://www.youmeek.com/ 常用的快捷键keymap 提示: ctrl+N:快速打开一个类 Ctrl+P 方法参数提示显示 Ctrl+J 提示自定义模板 Ctrl+O ...
- stm32之通用定时器TIM
STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由 ...
- 转化json
/// <summary> /// 转换成JSON字符串 /// </summary> /// <param name="jsonObject"> ...
- C# socket网络编程 基于TCP协议
socket 服务器端: 1.创建socket Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ...
- Java IO5:管道流、对象流
前言 前面的文章主要讲了文件字符输入流FileWriter.文件字符输出流FileReader.文件字节输出流FileOutputStream.文件字节输入流FileInputStream,这些都是常 ...
- Delphi 接口托管实现
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...