0
点赞
收藏
分享

微信扫一扫

Java NullPointerException避坑技巧:新手也能学会的NPE杜绝方法


你是不是也有过这种经历?写了段 Java 代码,编译的时候啥错没有,一运行直接蹦出个 NullPointerException(简称 NPE),盯着屏幕半天都没搞懂 —— 我明明给变量赋值了啊,咋就 “空” 了呢?尤其是刚学 Java 那会,每次遇到这玩意儿都头大,查半天 bug 才发现,原来就是某个对象没真正创建出来,白忙活一场。

其实 NPE 说穿了一点都不复杂,简单说就是:你想操作一个对象(比如调用它的方法、访问它的属性),但这个对象压根没被 “激活”,是个 “空架子”(也就是 Java 里的 null)。Java 这门语言很较真,它没法对一个 “空架子” 做任何操作,一碰到这种情况就会直接抛错,告诉你 “这东西不存在,我没法干活”。

举个最常见的例子,很多新手用集合的时候会这么写:

List nameList = new ArrayList<>();
String first Name = nameList.get(0);
System.out.println(firstName.length());

你想想看,刚 new 出来的 ArrayList 里连一个元素都没有,nameList.get (0) 能拿到啥?肯定是 null 啊!这时候再去调用 length () 方法,Java 能不抛 NPE 吗?我之前带过一个实习生,就因为这个错查了一下午,最后找到问题的时候拍着大腿说 “原来这么简单”,是不是特真实?

还有一种更隐蔽的坑,就是调用别人写的方法时,没考虑返回值可能是 null。比如你写了个获取用户信息的方法 getUserById (Long id),默认觉得 “只要传了 id,肯定能拿到用户”,于是直接这么用:

User user = getUserById (123L);
String userName = user.getUserName ();

但万一数据库里根本没有 id=123 的用户,getUserById () 返回的就是 null 啊!这时候 user.getUserName () 一执行,NPE 立马就来。我之前做项目的时候,就因为没处理第三方接口返回的 null,上线前测试没测出来,差点出线上事故,后来加了个 if (user != null) 的判断才搞定,亲测有效!

那咱到底咋避免踩 NPE 的坑呢?其实也不用太复杂,记住几个小技巧就行。

首先,一定要养成 “先判空再使用” 的习惯。不管是操作自己创建的对象,还是调用别人的方法,只要这个对象有可能是 null,就先加个 if 判断。比如刚才的集合例子,先判断 nameList.size () > 0,再去拿元素;用户信息的例子,先判断 user != null,再去获取用户名。可能有人会说 “这样写会不会太麻烦?多写好多行代码”,但你想想,比起出了错查半天,多写一行判断是不是划算多了?

其次,Java 8 之后出的 Optional 类,简直是处理 null 的神器,强烈推荐你用起来。它的作用就是把可能为 null 的对象 “包起来”,强制你去处理 null 的情况,避免直接操作 null 对象。比如刚才的 getUserById (),可以改成返回 Optional:

Optional userOpt = Optional.ofNullable (getUserById (123L));
// 如果有用户,就打印用户名;没有就打印 “用户不存在”
userOpt.ifPresent (user -> System.out.println (user.getUserName ()));
// 或者给个默认值
User user = userOpt.orElse (new User ("默认用户"));

这样就算 getUserById () 返回 null,也不会抛 NPE,是不是很省心?不过这里要提醒一句,别把 Optional 当参数传,也别用它来包装集合(比如 Optional<List>),不然反而会增加代码复杂度,这也是很多人容易踩的小坑。

另外,调试 NPE 的时候也有技巧,别光盯着报错行看。报错行告诉你 “这里出了 NPE”,但问题可能出在前面的赋值步骤。比如报错行是 user.getUserName (),那你就往前找:user 是在哪定义的?是调用哪个方法拿到的?那个方法有没有可能返回 null?用 IDE 的断点调试,一步一步看变量的值,很快就能找到问题所在,比瞎猜强多了。

对了,还有个小细节很多人容易忽略:数组初始化的时候,如果没给元素赋值,默认也是 null。比如 String [] arr = new String [3]; 这时候 arr [0]、arr [1]、arr [2] 全都是 null,你要是直接用 arr [0].length (),照样会出 NPE。所以数组用之前,也得检查元素是不是 null。

你之前有没有踩过 NPE 的坑?是因为没判空,还是没处理方法返回值?评论区说说你的经历,让大家也避避坑~毕竟谁都不想因为一个小小的 null,浪费半天调试时间,对吧?

我是【即兴小索奇】,点击关注,后台回复 领取,获取更多相关资源

举报

相关推荐

0 条评论