从零开始学Java之大名鼎鼎的NullPointerException到底该怎么处理?

作者 :孙玉昌,昵称【一一哥 】,另外【壹壹哥】也是我哦

千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者

前言

在上一篇文章中,壹哥给大家讲解了该如何自定义异常,以及如何处理自定义异常。接下来壹哥会带大家再来单独看一个很常见的异常--空指针异常,这个可以说是每个Java程序员都必知的异常,所以我们不得不单独学习一下。

------------------------------前戏已做完,精彩即开始----------------------------

全文大约【2700】 字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

配套开源项目资料

Github: github.com/SunLtd/Lear...

Gitee: 一一哥/从零开始学Java

一. 简介

你要问壹哥,Java中哪个异常最有名,那就不得不说NullPointerException!

NullPointerException,空指针异常,简称为NPE。这对Java程序员来说,可以说是一个无人不知、无人不晓的异常了!空指针异常往往是由于程序员没有考虑到变量或者对象的值可能为null,或者没有对null值进行判断导致的。所以当我们试图访问null对象或者是对null对象进行操作时,就会抛出NullPointerException异常。

NullPointerException异常在运行时被抛出,如果不加以处理,会导致程序的中断或者崩溃,因此我们在编写Java程序时,要格外注意避免空指针异常的发生。

二. 产生原因

之所以会出现NullPointerException空指针异常,最根本的原因只有一个,那就是"对象为空" ,这和很多单身狗的毛病一样,hiahia😺。也就是说,当一个对象为null时,你还非得调用该对象的方法或字段,此时JVM就会产生NullPointerException,例如:

java 复制代码
public static void main(String[] args) {
    String s = null;
    System.out.println(s.toUpperCase());
}

当上面这段代码运行时,肯定会产生空指针异常,因为对象"s"是null。也就是我们没有给该对象初始化赋值,它就是一个空壳子,你还非要使用它,这时就会出事。

三. 典型情况

虽然我们现在已经知道引发空指针异常的原因了,但为了让大家避免这种常见的异常,壹哥还是想给大家列举几个会引发空指针异常的典型情况。

3.1 对空对象调用方法或访问属性

当一个对象为null时,它就没有任何属性和方法,如果我们在这个空对象上调用方法或访问属性,就会引发空指针异常。例如:

java 复制代码
String str = null;
int length = str.length();  // 会抛出空指针异常

3.2 数组元素为null

在Java中,数组中的元素也可能会为null。如果我们在一个null数组元素上调用方法或访问属性,同样会抛出空指针异常。例如:

java 复制代码
String[] strs = new String[3];
strs[0] = "Hello";
strs[1] = null;
int length = strs[1].length();  // 会抛出空指针异常

3.3 参数为null

在调用方法时,如果参数为null,而方法内部却需要使用这个参数,也会抛出空指针异常。例如:

java 复制代码
public void printString(String str) {
    System.out.println(str.length());
}

String str = null;
printString(str);  // 会抛出空指针异常

四. 解决办法

为了避免空指针异常的发生,我们需要加强对变量和对象的判断,如果发现其值为null,就需要及早进行处理,例如设置默认值或者抛出异常。我们要知道,NullPointerException其实是一种代码逻辑错误,遇到NullPointerException,要遵循"早暴露、早修复"的原则,不要使用catch语句来隐藏这种编码错误! 比如下面这样的代码就不行:

java 复制代码
// 错误示例: 捕获NullPointerException
try {
    transferMoney(from, to, amount);
} catch (NullPointerException e) {
    //不要去捕获空指针异常!
}

接下来壹哥给大家列举几个常用的避免空指针异常的方法。

4.1 使用条件判断语句

通过判断变量是否为null,可以避免空指针异常的发生。例如:

java 复制代码
String str = null;
if (str != null) {
    int length = str.length();
}

4.2 使用对象初始化语句

我们在使用对象之前,确保要对该对象进行初始化,这样就可以保证对象不为null。例如:

java 复制代码
String str = "";
int length = str.length();

我们在编写业务逻辑时,使用空字符串""表示未填写,而不要用默认的null,""空串要比null安全得多,这可以避免很多NullPointerException。

4.3 使用Objects.requireNonNull()方法

Objects.requireNonNull()方法可以判断参数是否为null,如果是null,则会抛出NullPointerException异常。例如:

java 复制代码
String str = null;
Objects.requireNonNull(str, "str不能为空");  // 会抛出NullPointerException异常

4.4 返回空数组

如果我们使用数组时,某个数组没有数据,此时可以返回一个元素为空的数组,但是不要返回null,比如:

java 复制代码
public String[] getData(String item) {
    if (getItem(item) == 0) {
        // 返回空数组而不是null:
        return new String[0];
    }
    ...
}

这样调用方就不用检查结果是否为null。

4.5 使用Optional

Optional是Java 8中引入的一个非常有用的类,用于解决null值问题。它是一个容器对象,可能包含非空值或空值,主要目的是减少代码中的空指针异常,当调用方一定要判断某个对象是否为null时,就可以考虑使用Optional。接下来壹哥给大家编写一个简单的Optional案例。

java 复制代码
import java.io.IOException;
import java.util.Optional;

/**
 * @author 一一哥Sun 
 */
public class Demo13 {
    public static void main(String[] args) throws IOException {
        String str="一一哥";
        //创建一个包含非空值的Optional对象。如果传入的值为null,则会抛出NullPointerException异常。
        Optional<String> optional = Optional.of(str);
        if(optional.isPresent()) {
            String value = optional.get();
            System.out.println("value="+value);
        }else {
            System.out.println("字符串为空");
        }
        //ofNullable方法
        String name = null;
        //Optional.ofNullable静态工厂方法,创建一个包含指定值的Optional对象,如果传入的值为null,则返回一个空的Optional对象
        Optional<String> optionalName = Optional.ofNullable(name);
        String orElse = optionalName.orElse("Unknown");
        System.out.println("值="+orElse);
    }
}

我们可以使用 Optional.of 静态工厂方法来创建一个包含非空值的 Optional 对象,如果传入的值为 null,则会抛出 NullPointerException 异常。并可以使用 isPresent() 方法来判断 Optional 对象是否包含非空值。如果包含非空值,则返回 true,否则返回 false。

也可以使用 Optional.ofNullable 静态工厂方法,来创建一个包含指定值的 Optional 对象,如果传入的值为 null,则会返回一个空的 Optional对象。然后使用 orElse() 方法来获取 Optional 对象中包含的值,如果 Optional 对象为空,则返回指定的默认值。

关于Optional的用法还有很多,以后壹哥会出一个Java新特性的专题系列,这里就不再细说了,敬请期待哦。

4.6 定位空指针异常

当我们编写的代码真的产生了空指针异常,那该怎么办呢?壹哥前面就跟大家说过,产生空指针异常的根本原因就是因为"对象为空",所以解决的办法就是先找到这个为空的对象,然后给这个对象赋值,只要对象不为空,这个空指针异常就解决了。听起来也不难,但真的开发时,有时候经验不丰富的程序员,可能一时半会还找不到是哪个对象为空了。因为我们的项目中,对象实在太多了!比如下面这样的代码:

java 复制代码
a.b.c.method()

这里的a、b、c都是对象,假如就是这一行代码产生了空指针,你说到底是哪个对象为空?有可能是a为空,也有可能是b,也有可能是c,通常我们得一个对象一个对象进行判断,比如通过打印日志进行判断:

java 复制代码
System.out.println(a);
System.out.println(a.b);
System.out.println(a.b.c);

但是这样写代码,就显得啰嗦且低效!为了改善这种问题,在JDK 14中推出了新的API,JVM可以直接给出详细的信息,告诉我们null对象到底是哪个。在JDK 14中,如果是上面的代码产生了空指针异常,会出现这样的提示信息:... because "....a.b" is null....意思是b对象为null。但该功能默认是关闭的,我们需要给JVM添加一个-XX:+ShowCodeDetailsInExceptionMessages参数启用它,如下:

java 复制代码
java -XX:+ShowCodeDetailsInExceptionMessages Main.java

以上就是壹哥列举出来的几种避免及检查空指针异常的常用方法,希望你可以掌握。

总之,我们在编写Java程序时,要格外注意避免空指针异常的发生,加强对变量和对象的判断,养成良好的编码习惯,就可以极大地降低NullPointerException的产生。如果发现值为null,就需要及早进行处理,避免程序中断或者崩溃。

------------------------------正片已结束,来根事后烟----------------------------

五. 结语

这样,壹哥就把空指针这种特别常见的异常单独给大家分析了一下,希望大家以后遇到这种异常能够知道怎么解决。今天的重点内容如下:

  • NullPointerException的根本原因是对象为空;
  • 对空指针异常要早暴露,早修复,不要使用catch进行捕获;
  • 可以启用Java 14的增强异常来定位空指针异常的产生位置。

另外如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。

相关推荐
Penge6661 天前
Go 接口编译期断言
后端
我是一颗柠檬1 天前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试
橙淮1 天前
并发编程(六)
java·jvm
拽着尾巴的鱼儿1 天前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影1 天前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
Ceelog1 天前
久坐党自救指南:屏幕前 8 小时,身体到底在经历什么
前端·后端
EntyIU1 天前
JVM内存与GC笔记
java·jvm·笔记
XS0301061 天前
并发编程 六
java·后端
yaoxin5211231 天前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道1 天前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试