空指针是我们 Java 开发人员经常遇到的一个基本异常,这是一个极其普遍但似乎又无法根治的问题。

本文,栈长将带你了解什么是空指针,还有如何有效的避免空指针。

什么是空指针?

当一个变量的值为 null 时,在 Java 里面表示一个不存在的空对象,没有实际内容,没有给它分配内存,null 也是对象成员变量的默认值。

所以,一个对象如果没有进行初始化操作,这时候,如果你调用这个对象的方法或者变量,就会出现空指针异常。

如下面示例会发生空指针异常:

Object object = null;
String string = object.toString();

从类结构图来看,空指针它是属于运行时异常 RuntimeException 的子类,它不是捕获型的,只有在程序运行时才可能报出来,而且会造成程序中断。

什么是运行时异常及异常的分类请看这篇文章:一张图搞清楚 Java 异常机制

如何避免空指针?

下面说几个空指针的几个最常见的案例及解决之道。

1、字符串比较,常量放前面

if(status.equals(SUCCESS)){

}

这个时候 status 可能为 null 造成空指针异常,应该把常量放前面,就能避免空指针异常。

if(SUCCESS.equals(status)){

}

这个应该在各种开发规范里面都会提到,也是最基础的。

2、初始化默认值

在对象初始化的时候给它一个默认值或者默认构造实现,如:

User user = new User();
String name = StringUtils.EMPTY;

3、返回空集合

在返回一个集合的话,默认会是 null,统一规范返回一个空集合。

举个 List 例子,如:

public List getUserList(){
List list = userMapper.gerUserList();
return list == null ? new ArrayList() : list;
}

这样接收方就不用担心空指针异常了,也不会影响业务。

4、断言

断言是用来检查程序的安全性的,在使用之前进行检查条件,如果不符合条件就报异常,符合就继续。

Java 中自带的断言关键字:assert,如:

assert name == null : "名称不能为空";

输出:

Exception in thread "main" java.lang.AssertionError: 名称不正确

不过默认是不启动断言检查的,需要要带上 JVM 参数:-enableassertions 才能生效。

Java 中这个用的很少,建议使用 Spring 中的,更强大,更方便好用。

Spring中的用法:

Assert.notNull(name,"名称不能为空");

5、Optional

Optional 是 JDK 8 新增的新特性,再也不用 != null 来判断了,这个在一个对象里面的多个子对象连续判断的时候非常有用。

这里不再详细介绍了,具体看这篇文章:JDK8新特性之Optional

这里大概介绍了 5 种,其实还有更多,如何避免空指针,一是要注意代码编写规范,二是要提高代码素养。在Java技术栈微信公众号后台回复关键字:Java,可以获取更多栈长整理的 Java 系列技术干货。

大家都有什么高见,欢迎留言分享!

本文原创首发于微信公众号:Java技术栈(id:javastack),关注公众号在后台回复 "Java" 可获取更多,转载请原样保留本信息。

别再写 bug 了,避免空指针的 5 个案例!的更多相关文章

  1. 花了2小时写bug

    程序员的工作,写bug,修bug,改bug 写了2小时逻辑关系,没写明白 比昨天多了一个返回上一层的功能 也很简单,清除下数组内容即可 emm..明天继续深究吧 dic = { "植物&qu ...

  2. switch case :在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了

    switch的case语句可以处理int,short,byte,char类型的值, 因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出. char a = 'e ...

  3. 传递的值是this,在js里就不用再写$(this)

    <input class="editinput" value="${detail.earlymoneyrmb}" name="earlymone ...

  4. 以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurerAdapter中的addViewControllers方法即可达到效果了

    以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurerAdapter中的addViewC ...

  5. 再写一篇tps限流

    再写一篇tps限流 各种限流算法的称呼 网上有很多文章介绍限流算法,但是对于这些算法的称呼与描述也是有点难以理解.不管那么多了.我先按我理解的维度梳理一下. 主要维度是:是正向计数还是反向计数.是定点 ...

  6. 缓存与数据库一致性之二:高并发下的key重建(先淘汰cache再写db)的问题

    一.为什么数据会不一致 回顾一下上一篇文章<缓存与数据库一致性之一:缓存更新设计>中对缓存.数据库进行读写操作的流程. 写流程: (1)先淘汰cache (2)再写db 读流程: (1)先 ...

  7. 程序员生存之道,多写bug!

    1.代码写得好,bug少,看起来就像闲人. 2.注释多,代码清晰,任何人接手非常方便,看起来谁都都可以替代. 3.代码写得烂,每天风风火火改bug,各种救火,解决各种线上重大问题,于是顺理成章为公司亮 ...

  8. 表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这种写法就是把组件嵌套改为配置方式

    表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这 ...

  9. 【优雅代码】04-1行代码完成多线程,别再写runnable了

    [优雅代码]04-1行代码完成多线程,别再写runnable了 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮 ...

随机推荐

  1. 理解go的闭包

    package main import ( "fmt" ) func test(a int) { a++ fmt.Println(a) } func test2() func() ...

  2. P1462 通往奥格瑞玛的道路 最短路

    题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...

  3. ECMAScript 6 之 let 和 const 命令

    1.let基本用法 1.1.声明变量 let声明的变量只在它所在的代码块有效. 1.2.不存在变量提升 var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined: let命令 ...

  4. Git 通过ssh 配置基于Host的差异配置

    Host gitlab.xxx.com HostName gitlab.xxx.com User user IdentityFile xxx\.ssh\id_rsa Host github.com H ...

  5. java自动化-关键字驱动在junit接口自动化的应用

    本文是继承上文的基础上进行的讨论,建议读者先阅读http://www.cnblogs.com/xuezhezlr/p/9097137.html和https://www.cnblogs.com/xuez ...

  6. 如何修改SnipeIT的部分设置

    作为一款开源的资产管理系统,Snipe-IT非常的好用又结实,但是原始设置对中国用户有些不方便,部分汉化没有完成,需要直接修改代码,下面把常用的修改记录如下: 1.修改资产打印标签中的文本名称 找到  ...

  7. Winform消息与并行的形象比喻

    有一次我给同事讲述跨线程调用时使用了高速行驶的并行列车来比喻,感觉比较形象. 线程列车 多线程就像多个并行的列车,每个线程在各自的轨道上不断向前行驶.主界面所在的线程称为UI线程,也叫主线程,主线程依 ...

  8. Markdown常用快捷键

    Markdown使用的符号:井号,星号,大于号,中括号,竖线,横杠,波浪线,反引号 # ,*, > ,[],|,-,~,` 井号 + 空格:根据空格的个数显示各标题的大小 标题一 标题二 标题三 ...

  9. jquery for循环

    第一种: for(var i=0,len=$len.length; i<len; i++){//alert($len.eq(i).html());$zongshu=$zongshu+$len.e ...

  10. comutil

    使用该工具库,通常包含comsuppw.lib.kernel32.lib. _com_util::ConvertBSTRToString 将VT_BSTR类型转换为普通字符串.