首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在Java中如何避免“!=null”式的判空语句?

在Java中如何避免“!=null”式的判空语句?

作者头像
哲洛不闹
发布于 2018-09-19 03:20:12
发布于 2018-09-19 03:20:12
4K00
代码可运行
举报
文章被收录于专栏:java一日一条java一日一条
运行总次数:0
代码可运行

问题描述:

我整天都是在跟Java打交道。我在Java开发中最常用的一段代码就是用object != null在使用对象之前判断是否为空。这么做是为了避免NullPointerException。但是我发现这样检测代码实在是太丑了,而且及其不可读。

那有没有一种优雅的替代方法呢?

问题补充:

再清晰化一下我的问题,我是在强调在使用对象的属性或者方法之前,确保它不为空的重要性,就像下面这段代码一样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (someobject != null) {
    someobject.doCalc();
}

这么些我是为了避免抛NullPointerException异常,我不知道这个对象是不是空的。正由于这些判空代码,导致我的代码血花四溅,相当惨不忍睹。

最佳解答:

对于我来说,这就是一个初级开发者走向中级开发者过程中有时候都会碰到的合理问题:他们不知道也不太信任自己所使用的约定,并且过度的去检查空值情况。另外,当他们写代码的时候,总是会让方法去返回一些值,因此就可以由方法调用方去检查空值了。

换句话说,有两种情况会出现判空语句:

  • null返回值按找约定是正常的返回值
  • null返回值不是正常的返回值

第二种情况很简单。可以使用assert来判断或者是允许程序报错(即抛NullPointerException)。断言是一个被充分利用的Java特性,在1.4版本中加入了这个特性。语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
assert *<condition>*

或者是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
assert *<condition>* : *<object>*

object的toString()输出会被包括在错误信息中。

当判断条件为false的时候assert语句就会抛出Error(AssertionError)错误。在默认情况下,Java虚拟机是不会理会断言语句的。当需要使用此特性的时候可以给JVM虚拟机传入-ea参数来启用它。同时也可以针对单个的Java类或者是包来使用断言特性。这就意味着可以在开发测试的过程中来使用断言验证代码,而在生产环境就关闭这个特性,尽管我已经测试显示断言功能并不会对应用程序产生任何影响。

这个案例中不使用断言是可以的,因为代码本身就是会报错的,就像假如你使用断言之后一定会抛出Error错误一样。用和不用的区别就是可以尽早的去发现错误,用更有意义,更加丰富的信息来描述这个错误,这样你就可以帮助你弄清楚为什么会发生这种错误(假如这种错误你确实不想它发生)。

第一种情况就要难解释一点了。如果你对你调用的代码没有控制权的话,你就惨了。如果null返回值是正常的话,那你就必须去检查它了。

如果可以控制你调用代码(当然常常还是有控制权的),那就是另一回事儿了。还是尽量的不去使用null返回值。对于返回集合的方法很简单,只需要返回空的集合就可以了,而不是null。

对于返回值不是集合的方法,就要麻烦一点了。假如碰到下面的情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

Parse接口从标准输入中接受指令,并去执行一些操作,可能会去用这个接口实现一个命令行工具。那现在就有个约定当没找到合适的操作指令时,就返回空值。那这儿就得去验空值了。

一种可选办法就是不使用空返回值,而是空对象模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

来对比下下面这两种:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // 这儿当然得空值判断一下啊,这儿根本就不应该出现空值
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ParserFactory.getParser().findAction(someInput)
.doSomething();

明显下面这种写法更加简明清晰。

其实在findAction()方法中直接抛出更加有意义的错误信息是完全可以的。特别是你在依赖用户输入的应用中。对于findAction()方法来说抛出一个带有说明的异常要比光秃秃的抛出一个NullPointerException要好的多。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try{
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

要是你觉得使用try/catch机制比较丑的话,那就给用户比较有意义的反馈。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Action findAction(final String userInput){
    /* Code to return requested Action if found */
    return new Action(){
        public void doSomething(){
            userConsole.err("Action not found: "
+userInput);
        }
    }
}

首发:译邻

原文链接: Stack Overflow 翻译: ImportNew.com - strongme http://www.importnew.com/13002.html译文链接:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2015-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java一日一条 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何在Java代码中去掉烦人的“!=null”
最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢?
java思维导图
2020/04/21
1.5K0
为什么不建议你用去 “! = null” 做判空?
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/03/04
7440
Java空指针异常处理:判空、Optional与Assert解析
在Java编程中,空指针异常(NullPointerException)是最常见的运行时错误之一。本文将深入探讨三种处理空指针异常的方法:传统的判空检查、Java 8引入的Optional类以及使用断言(Assert)。通过代码示例和应用场景分析,帮助开发者理解并选择最适合的方案以提升程序健壮性。
Yeats_Liao
2024/12/27
9190
Java空指针异常处理:判空、Optional与Assert解析
优雅判空
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/18
1.5K0
阿里P8架构师浅析如何避免在Java中检查Null语句
通常,在Java代码中处理null变量、引用和集合很棘手。它们不仅难以识别,而且处理起来也很复杂。事实上,在编译时无法识别处理null的任何错误,会导致运行时NullPointerException。在本教程中,我们将了解在Java中检查null的必要性以及帮助我们避免在代码中进行空检查的各种替代方法。
本人秃顶程序员
2019/05/21
1.4K0
Java 中关于 Null 的这些事儿你知道吗
对于 Java 程序员来说,null 一直是令人头疼的问题,经常会受到 NullPointerException 的蹂躏和壁咚。Java 的发明者也承认这是一个巨大的设计错误。
cxuan
2019/08/26
8260
Java 中关于 Null 的这些事儿你知道吗
Java中有关Null的9件事
对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java。
哲洛不闹
2018/09/19
7770
Java设计模式之(二)——工厂模式
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
用户4268038
2021/11/18
7310
Java8中使用Optional处理null对象
  Optional 是一个容器对象,可以存储对象、字符串等值,当然也可以存储 null 值。Optional 提供很多有用的方法,能帮助我们将 Java 中的对象等一些值存入其中,这样我们就不用显式进行空值检测,使我们能够用少量的代码完成复杂的流程。
Kevin_Zhang
2021/06/22
2.3K0
Java8中使用Optional处理null对象
.NET单元测试的艺术-3.测试代码
开篇:上一篇我们学习单元测试和核心技术:存根、模拟对象和隔离框架,它们是我们进行高质量单元测试的技术基础。本篇会集中在管理和组织单元测试的技术,以及如何确保在真实项目中进行高质量的单元测试。
Edison Zhou
2018/08/20
6200
.NET单元测试的艺术-3.测试代码
还只会 null != obj 判空,10招让你彻底告别空指针异常!
NPE异常相信 Java 程序员都很熟悉,是 NullPointerException 的缩写;最近业务需求开发的有点着急,测试环境就时不时的来个NPE异常,特别的头疼;作为出镜率最高的异常之一,一旦入行 Java 开发,可以说它将伴随着你整个职业生涯;不管是新手小白、还是老司机,对NPE异常那是又“爱”又狠,爱的主要原因是处理起来简单,恨当然是一个不小心就会踩坑;为了提高代码的质量,NPE异常是必须要消灭掉的;
一行Java
2023/09/04
1.2K0
还只会 null != obj 判空,10招让你彻底告别空指针异常!
null 不好,我真的推荐你使用 Optional
Doug Lea 是一位美国的计算机科学家,他是 Java 平台的并发和集合框架的主要设计者之一。他在 2014 年的一篇文章中说过:“Null sucks.”1,意思是 null 很糟糕。他认为 null 是一种不明确的表示,它既可以表示一个值不存在,也可以表示一个值未知,也可以表示一个值无效。这样就会导致很多逻辑错误和空指针异常,给程序员带来很多麻烦。他建议使用 Optional 类来封装可能为空的值,从而提高代码的可读性和健壮性。
wayn
2023/11/18
3720
null 不好,我真的推荐你使用 Optional
开发中造成空指针的常见写法,如何预防!
反例:public int f () { return Integer 对象}, 如果为 null,自动解箱抛 NPE。
小熊学Java
2023/07/16
9350
开发中造成空指针的常见写法,如何预防!
写给精明Java开发者的测试技巧
我们都会为我们的代码编写测试,不是吗?毫无疑问,我知道这个问题的答案可能会从 “当然,但你知道怎样才能避免写测试吗?” 到 “必须的!我爱测试”都有。接下来我会给你几个小建议,它们可以让你编写测试变得更容易。那会帮助你减少脆弱的测试,并保证应用程序更加健壮。
哲洛不闹
2018/09/19
2.3K0
Java函数式编程之Optional
java.util.Optional是JDK8中引入的类,它是JDK从著名的Java工具包Guava中移植过来。本文编写的时候使用的是JDK11。Optional是一个包含了NULL值或者非NULL值的对象容器,它常用作明确表明没有结果(其实明确表明存在结果也可以用Optional表示)的方法返回类型,这样可以避免NULL值带来的可能的异常(一般是NullPointerException)。也就是说,一个方法的返回值类型是Optional,则应该避免返回NULL,而应该让返回值指向一个包含NULL对象的Optional实例。Optional的出现为NULL判断、过滤操作、映射操作等提供了函数式适配入口,它算是Java引入函数式编程的一个重要的里程碑。
Throwable
2020/06/23
1.7K0
Java编程规范-缺陷预防
在 Java 中,有八种基础数据类型,其中 4 种整形, 2 种浮点类型, 1 种用于表示 Unicode 编码的字符单元的字符类型 char 和 1 种用于表示真假的 boolean 类型,其中一些和 C 差异 较 大,开发人员需要注意这些差异: 1、Java 不支持 unsigned ; 2、在 C 中,布尔值和数字类型是可以转换的,在 Java 中不可以, boolean 和数值类型之间不能进行转换; 3、在 C 中,某些类型在不同系统中,所占空间大小不同,比如 long 类型,在 32 位系统中占 4 字节,在 64 位系统中占 8 字节,但 Java 中 long 类型无论在 32 位系统还是 64 位系统中,都是占 8 字节; 4、在 C 中, char 类型占 1 字节空间,而在 Java 中占 2 字节 ,意义也发生了变化, Java 中的 char 用于存储 Unicode 编码的字符 ;
向着百万年薪努力的小赵
2022/12/02
6250
关于 if (someobject != null) 的问题
下内容来自于在 StackOverflow 上的有一个有趣的讨论,说的话题很小,就是对于这样的对象为空的检查:
四火
2022/07/18
6420
关于 if (someobject != null) 的问题
NullPointerException : Attempt to invoke a method on a null object reference 完美解决方法
大家好,我是默语。今天的主题是大家在Java开发中经常遇到的经典错误:NullPointerException(简称NPE)。这个错误通常发生在尝试对null对象调用方法时,它不仅困扰新手,也会让经验丰富的开发者头疼。在这篇文章中,我将详细剖析导致此问题的常见原因,并提供一些最佳解决方案。关键词:NullPointerException、Java错误、null对象引用问题修复。🚀
默 语
2024/11/22
8890
Java 中的 Optional
从 Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异常。
BUG弄潮儿
2020/11/11
5650
Stack Overflow 上最火的一个问题:什么是 NullPointerException
在逛 Stack Overflow 的时候,发现最火的问题竟然是:什么是 NullPointerException(java.lang.NullPointerException),它是由什么原因导致的,有没有好的方法或者工具可以追踪它发生的原因?
沉默王二
2019/10/21
9490
相关推荐
如何在Java代码中去掉烦人的“!=null”
更多 >
领券
一站式MCP教程库,解锁AI应用新玩法
涵盖代码开发、场景应用、自动测试全流程,助你从零构建专属AI助手
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档