为什么牛逼的程序员都不用 “ ! = null " 做判空?

为什么牛逼的程序员都不用 “ ! = null “ 做判空? 问题 为了避免空指针调用,我们经常会看到这样的语句 ...if (someobject != null) { someobject.doCalc();}... 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢? 精华回答 这是初、中级程序猿经常会遇到的问题。他们总喜欢在方法中返回null,因此,在调用这些方法时,也不得不去判空。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。 吐槽完毕,回到这个题目本身: 阅读详情

# 问题

为了避免空指针调用,我们经常会看到这样的语句   

...if (someobject != null) {
    someobject.doCalc();}...

最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢?

# 精华回答

这是初、中级程序猿经常会遇到的问题。他们总喜欢在方法中返回null,因此,在调用这些方法时,也不得不去判空。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。

吐槽完毕,回到这个题目本身:

进行判空前,请区分以下两种情况:

1、null 是一个有效有意义的返回值(Where null is a valid response in terms of the contract; and)

2、null是无效有误的(Where it isn't a valid response.)

你可能还不明白这两句话的意思,不急,继续往下看,接下来将详细讨论这两种情况

# 先说第2种情况

null就是一个不合理的参数,就应该明确地中断程序,往外抛错误。这种情况常见于api方法。例如你开发了一个接口,id是一个必选的参数,如果调用方没传这个参数给你,当然不行。你要感知到这个情况,告诉调用方“嘿,哥们,你传个null给我做甚"。

相对于判空语句,更好的检查方式有两个

(1)assert语句,你可以把错误原因放到assert的参数中,这样不仅能保护你的程序不往下走,而且还能把错误原因返回给调用方,岂不是一举两得。(原文介绍了assert的使用,这里省略)

(2)也可以直接抛出空指针异常。上面说了,此时null是个不合理的参数,有问题就是有问题,就应该大大方方往外抛。

# 第1种情况会更复杂一些。

这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。

# 这里给一些实践建议:

1、假如方法的返回类型是collections,当返回结果是空时,你可以返回一个空的collections(empty list),而不要返回null,这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接print list.size(),又无需担心空指针问题。(什么?想调用这个方法时,不记得之前实现该方法有没按照这个原则?所以说,代码习惯很重要!如果你养成习惯,都是这样写代码(返回空collections而不返回null),你调用自己写的方法时,就能大胆地忽略判空)

2、返回类型不是collections,又怎么办呢?

那就返回一个空对象(而非null对象),下面举个“栗子”,假设有如下代码

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

其中,Parse有一个接口FindAction,这个接口会依据用户的输入,找到并执行对应的动作。假如用户输入不对,可能就找不到对应的动作(Action),因此findAction就会返回null,接下来action调用doSomething方法时,就会出现空指针。

解决这个问题的一个方式,就是使用Null Object pattern(空对象模式)

# 我们来改造一下

类定义如下,这样定义findAction方法后,确保无论用户输入什么,都不会返回null对象   

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;
    }
  }}

对比下面两份调用实例

1、冗余:每获取一个对象,就判一次空

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing} else {
  action.doSomething();}

2、精简

ParserFactory.getParser().findAction(someInput).doSomething();

因为无论什么情况,都不会返回空对象,因此通过findAction拿到action后,可以放心地调用action的方法。

# 其他回答精选:

1、如果要用equal方法,请用object<不可能为空>.equal(object<可能为空>))

例如使用   :

"bar".equals(foo)

而不是   

foo.equals("bar")

2、Java8或者guava lib中,提供了Optional类,这是一个元素容器,通过它来封装对象,可以减少判空。不过代码量还是不少。不爽。

3、如果你想返回null,请停下来想一想,这个地方是否更应该抛出一个异常

作者:lizeyang

来源:blog.youkuaiyun.com/lizeyang/article/details/40040817

最后,推荐给大家一个干货有料的公众号:JavaCat,该号没有广告,天天都是干货,老Java带你做项目实践,永不迷路:

长按关注,学习Java
Rk3128投影仪救砖操作和固件分享思路 大家搞一条比较硬的东西,插入耳机口,就可以进入刷机模式了的,我的机器是这样的,大家也可以试试。(看不懂可以往下看) 阅读详情

相关推荐

诠视MR眼镜Unity开发设置_Unity2020.3.38

请按照如下设置Android SDK 和 Gradle。打包前先将Unity切换到Android模式。Preferences 设置。

m0_71932574的博客 603

db2 空值转换函数_db2数据库的null值替换

db2数据库的null值替换DB2中空值处理1. 输入参数为字符类型,且允许为空的,可以使用COALESCE(inputParameter,'')(或者value(inputParameter,''))把NULL转换成'';value()2. 输入类型为整型,且允许为空的,可以使用COALESCE(inputParameter,0),把空转换成0;3. 输入参数为字符类型,且是非空非空格的,可以使...

weixin_39629876的博客 2900

基于51单片机的多功能智能路灯控制系统(仿真+代码+原理图)

智能路灯控制系统主要由51单片机最小系统+1602显示模块+DS1302时钟模块+光强检测模块+按键输入模块+声光报警模块+LED照明模块+状态检测电路+人体车辆红外检测模块组成。能实现以下功能: 1.能够按键设定系统时间、工作时间、光照阈值 2.工作时间内路灯点亮,凌晨12点后路灯关闭,有人或车通过是,路灯点亮10s 3.非工作时间光照强度低于阈值,路灯点亮 4.能够检测系统工作状态,路灯应亮未亮,声光报警 5.具备手动控制,能够切换自动/手动控制功能

u012759563的博客 8178

关于DB2 COALESCE函数

1. 输入参数为字符类型,且允许为空的,可以使用COALESCE(inputParameter,)把NULL转换成;2. 输入类型为整型,且允许为空的,可以使用COALESCE(inputParameter,0),把空转换成0;3. 输入参数为字符类型,且是非空非空格的,可以使用COALESCE(inputParameter,)把NULL转换成,然后判断函数返回值是否为

Ubox的专栏 1538

华南理工大学电子与信息学院23年预推免复试面试经验贴

华南理工大学电子与信息学院23年预推免复试面试经验贴

Scut_Ty的博客 3297

GPU架构-SIMT

本文深度剖析了GPU的SIMT架构,从硬件实现层面解析其与SIMD的本质差异。SIMT通过将32个线程捆绑为warp执行,在标量编程模型下实现数据并行。文章对比了SIMD和SIMT的执行模型、分支处理机制及存储层次,指出SIMT是对SIMD的虚拟化抽象。重点分析了Volta架构引入的独立线程调度技术,以及访存合并对性能的关键影响。通过定量数据展示了各代GPU架构的寄存器文件规模和线程调度机制,为开发者优化GPU程序提供了硬件层面的理论基础。

技术引领业务创新 973

去掉烦人的 “ ! = null " (判空语句)

转自:优快云 作者:lizeyangblog.youkuaiyun.com/lizeyang/article/details/40040817问题为了避免空指针调用,我们经常会看到这样的语句 ...

HollisChuang's Blog 1284

基本模型 PINNs : Physics Informed Neural Networks

系列最开始当然要提到很经典的文章 —— Physics-informed neural networks: A deep learning framework for solving forward and inverse problems involving nonlinear partial differential equations 。 这篇文章是布朗大学的助理教授Maziar Rais...

waitingwinter的博客 3万+

DB2中怎么对空值和NULL进行处理

1、输入参数为字符类型,且允许为空时,可以使用函数COALESCE(inputParameter,'')将值变为空字符串。 2、输入参数为整型,且允许为空时,可以使用函数COALESCE(inputParameter,0)将值变为0。 3、输入参数为字符类型,且非空非空格,可以使用函数COALESCE(inputParameter,'')将值变为字符串‘’,然后使用判断函数 判断是否为‘’。...

NeverGiveUp的博客 5169

CSP-J 复试考点

可以用来训练思维,对于学习时间短的同学,动态规划可以帮助你迅速进入编程状态,也有助于帮你发现题目背后可能隐藏的更简便的算法。动态规划、贪心都是和子问题相关的,动态规划的基本思想是将一个大的问题划分成子问题,接着分别求解,而且能够将一些重复的计算记忆化,大大提高效率。难度加大,会涉及到二分、动态规划之类的算法,容易遗漏考虑点,不易得全分,考试的时候要注意全面性。一般是压轴题,算法不明显,剪枝的搜索、动态规划、状压 DP、树形 DP 、树、图等。枚举算法是指,列举出所有可能的取值,从中找出最优解。

GuanHeTian的博客 2214

AI 代码赋能短视频带货:服装及多赛道批量内容生产全流程实操

本文聚焦 AI 技术在短视频带货领域的落地应用,以服装赛道为核心,延伸至花卉绿植、图书、茶具等热门领域,系统拆解 AI 工具在选品、素材处理、视频制作(含动态效果、场景搭建)、运营优化等环节的实操方法。针对从业者普遍面临的 “内容生产低效”“无专业技术难出优质视频”“流量运营踩坑” 等痛点,提供从基础工具使用到高阶视频制作的全流程技术方案,助力相关从业者借助 AI 实现批量、高效的短视频内容产出。

m0_67958922的博客 3084

为什么牛逼的程序员都不用 “ ! = null ‘ 做判空

(empty list),而不要返回 null,这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接 print list.size(),又无需担心空指针问题。例如你开发了一个接口,id 是一个必选的参数,如果调用方没传这个参数给你,当然不行。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。这种情况下,null 是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时 null 算是表达了“空”的概念。

fuladulu的博客 421

YOLOv11 损失函数解析

YOLOv11 在 YOLO 系列的持续演进中,通过 ​多模态损失协同优化、动态任务感知机制 和 ​超轻量化设计,实现了检测精度与推理效率的再突破。其损失函数设计融合了前沿的几何建模、分布学习与自监督技术,显著提升了复杂场景下的鲁棒性。

浩瀚之水的专栏 6702

为什么牛逼的程序员都不用 “ ! = null ' 做判空?

为了避免空指针调用,我们经常会看到这样的语句。... if(someobject!=null){ someobject.doCalc(); } ...最终,项目中会存在大量...

程序IT圈 166

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 卸载 Navicat!事实已证明,正版客户端,它更牛逼……
下一篇: 为什么阿里巴巴禁止使用存储过程?
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值