Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 51059|回复: 0

[改善Java代码]小心switch带来的空值异常

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-10 22:19:06 | 显示全部楼层 |阅读模式

    使用枚举定义常量时,会伴有大量的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

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 01:04 , Processed in 0.068748 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表