使用枚举定义常量时,会伴有大量的switch语句判断,目的是伪类每个枚举项解释其行为,例如:

 public class Client {
public static void main(String[] args) { doSports(null);
} public static void doSports(Season season) {
switch (season) {
case Spring:
System.out.println("春天放风筝");
break;
case Summer:
System.out.println("夏天游泳");
break;
case Autumn:
System.out.println("秋天捉知了");
break;
case Winter:
System.out.println("冬天滑冰");
break;
default:
System.out.println("输入错误!");
break;
}
}
} enum Season {
Spring, Summer, Autumn, Winter;
}

上面的代码输入 了一个Season类型的枚举,然后使用switch进行匹配,目的是输出每个季节的活动.但是代码是否有问题?

doSports(null),似乎会打印出"输出错误",因为在switch中没有匹配到指定的值,所以会打印出default的代码块.

运行看结果:

Exception in thread "main" java.lang.NullPointerException
at cn.summerchill.test.Client.doSports(Client.java:12)
at cn.summerchill.test.Client.main(Client.java:8)

switch那一行报出了空指针...这就是枚举和switch的特性有关了...此问题也是在开发中经常发生.

目前Java中的switch语句只能判断byte,short,char,int类型(JDK7中已经允许使用String类型),这是Java编译器的限制,问题是为什么枚举类型也可以 跟在switch后面呢?

因为编译时,编译器判断出switch语句后面的参数是枚举类型,然后就根据枚举的排序值继续匹配,也就是说上面代码与以下代码相同:

public class Client {
public static void main(String[] args) { doSports(Season.Spring);
} public static void doSports(Season season) {
switch (season.ordinal()) {
case Season.Spring.ordinal():
System.out.println("春天放风筝");
break;
case Season.Summer.ordinal():
System.out.println("夏天游泳");
break;
case Season.Autumn.ordinal():
System.out.println("秋天捉知了");
break;
case Season.Winter.ordinal():
System.out.println("冬天滑冰");
break;
default:
System.out.println("输入错误!");
break;
}
}
} enum Season {
Spring, Summer, Autumn, Winter;
}

但是这样会报错的...在各个case语句上 报 case expressions must be constant expressions..但是书中却没有提到这一点....不知道为什么.....

switch语句是先计算season变量的排序值,然后与枚举常量的每个排序值进行对比.

在我们的例子中season的变量值是null,无法执行ordinal()方法,于是报空指针异常了.

解决方法也有很简单:在doSports()方法中判断输入的参数是否是null即可.

ordinal 单词是序数的意思. ordinal()方法获得的是从0开始的数字 .....Spring对应为0 ,Summer为1,Autumn为2,Winter为3

[改善Java代码]小心switch带来的空值异常的更多相关文章

  1. 提高你的Java代码质量吧:小心switch带来的空值异常

    一.分析  使用枚举定义常量时,会有伴有大量的switch语句判断,目的是为每个枚举解释其行为. 我们知道,目前的Java的switch语句只能判断byte.short.char.int类型(JDK7 ...

  2. [改善Java代码]在switch的default代码块中增加AssertionError错误

    switch的后跟枚举类型,case后列出所有的枚举项,这是一个使用枚举的主流写法,那留着default语句似乎没有任何作用了,程序已经列举出了所有的可能选项,肯定不会执行到default语句,. 错 ...

  3. [改善Java代码]多线程使用Vector或HashTable

    Vector是ArrayList的多线程版本,HashTable是HashMap的多线程版本,这些概念我 们都很清楚,也被前辈嘱咐过很多次,但我们经常会逃避使用Vector和HashTable,因为用 ...

  4. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  5. [改善Java代码]避免在构造函数中初始化其他类

    建议35: 避免在构造函数中初始化其他类 构造函数是一个类初始化必须执行的代码,它决定着类的初始化效率,如果构造函数比较复杂,而且还关联了其他类,则可能产生意想不到的问题,我们来看如下代码: publ ...

  6. [改善Java代码]别让null值和空值威胁到变长方法

    建议5:别让null值和空值威胁到变长方法 public class Client { public void methodA(String str,Integer... is){ } public ...

  7. [改善Java代码]避开基本类型数组转换列表陷阱

    开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题. 看代码: import java.util.Arrays; import ...

  8. [改善Java代码]枚举和注解结合使用威力更大

    注解的写法和接口很类似,都采用了关键字interface,而且都不能有实现代码,常量定义默认都是pulbic static final类型的. 他们的主要不同点是:注解在interface前加上@字符 ...

  9. [改善Java代码]用枚举实现工厂方法模式更简洁

    工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到 ...

随机推荐

  1. 【转】Nginx系列(二)--模块化

    原博文出于: http://blog.csdn.net/liutengteng130/article/details/46700977  感谢! 高度模块化的设计设Nginx架构的基础.在Nginx中 ...

  2. Java 任务调度

    1.普通方式 /** * 普通thread * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着, * 通过sleep方法来达到定时任务的效果.这样可以快速简单的实现 */ p ...

  3. 获取ie浏览器版本号

    /** * 获取ie浏览器版本号 * @returns */ function getInternetExplorerVersion(){ var version = -1; // Return va ...

  4. MVC神韵---你想在哪解脱!(十八)

    数据的修改视图 首先打开Movie控制器,添加一个返回数据修改视图的Edit()方法与一个对该视图中的表单提交进行处理的Edit()方法,代码如下所示: // GET: /Movies/Edit pu ...

  5. EasyUI datagrid添加右键菜单项

    js代码 //动态加载数据表格 function InitData() { $('#grid').datagrid({ url: '/Home/Query?r=' + Math.random(), / ...

  6. ModelMap和ModelAndView

    一.ModelMap和ModelAndView 1.1.ModelMap ModelMap对象主要用于传递控制方法处理数据到结果页面,也就是说我们把结果页面上需要的数据放到ModelMap对象中即可, ...

  7. hdu 2553 N皇后问题 (经典DFS)

    题目链接:点击链接 思路:用一维数组hang[num] = i,num表示第num行,i表示第i列,计算n = 1~10皇后的不同放置数量,然后打表 #include<stdio.h> # ...

  8. UVa297 Quadtrees

    // UVa297 Quadtrees // 题意:给两棵四分树的先序遍历,求二者合并之后(黑色部分合并)黑色像素的个数.p表示中间结点,f表示黑色(full),e表示白色(empty) // 算法: ...

  9. Android BLE开发之Android手机搜索iBeacon基站

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 上次讲了Android手机与BLE终端之间的通信,而最常见的BLE终端应该是苹果公司倡导的iBeacon基站. ...

  10. Codeforces Gym 100002 D"Decoding Task" 数学

    Problem D"Decoding Task" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com ...