zoukankan      html  css  js  c++  java
  • [改善Java代码]小心switch带来的空值异常

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

     1 public class Client {
     2     public static void main(String[] args) {
     3 
     4         doSports(null);
     5     }
     6 
     7     public static void doSports(Season season) {
     8         switch (season) {
     9         case Spring:
    10             System.out.println("春天放风筝");
    11             break;
    12         case Summer:
    13             System.out.println("夏天游泳");
    14             break;
    15         case Autumn:
    16             System.out.println("秋天捉知了");
    17              break;
    18         case Winter:
    19             System.out.println("冬天滑冰");
    20             break;
    21         default:
    22             System.out.println("输入错误!");
    23             break;
    24         }
    25     }
    26 }
    27 
    28 enum Season {
    29     Spring, Summer, Autumn, Winter;
    30 }

    上面的代码输入 了一个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

  • 相关阅读:
    Stl源码剖析读书笔记之Alloc细节
    Lua热更系统
    Linux C++线程池
    linux sort,uniq,cut,wc.
    (转)Linux grep
    用LogParser分析IIS请求压力
    (转)MySQL主从复制的常见拓扑、原理分析以及如何提高主从复制的效率总
    AIS相关资料
    python学习笔记
    (转)MySQL InnoDB修复笔记
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/5632671.html
Copyright © 2011-2022 走看看