详解Java中NullPointerException的处理方法

 更新时间:2023年08月31日 08:28:43   作者:一一哥Sun  
这篇文章将带大家来单独看一个很常见的异常--空指针异常,这个可以说是每个Java程序员都必知的异常,所以我们不得不单独学习一下,文中有详细的代码示例,需要的朋友可以参考下

一. 简介

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

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

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

二. 产生原因

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

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

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

三. 典型情况

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

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

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

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

3.2 数组元素为null

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

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

3.3 参数为null

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

public void printString(String str) {
    System.out.println(str.length());
}
String str = null;
printString(str);  // 会抛出空指针异常

四. 解决办法

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

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

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

4.1 使用条件判断语句

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

String str = null;
if (str != null) {
    int length = str.length();
}

4.2 使用对象初始化语句

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

String str = "";
int length = str.length();

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

4.3 使用Objects.requireNonNull()方法

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

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

4.4 返回空数组

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

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案例。

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 定位空指针异常

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

a.b.c.method()

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

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 -XX:+ShowCodeDetailsInExceptionMessages Main.java

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

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

五. 结语

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

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

以上就是详解Java中NullPointerException的处理方法的详细内容,更多关于Java NullPointerException处理的资料请关注脚本之家其它相关文章!

相关文章

  • SpringMvc中的Bean加载机制详解

    SpringMvc中的Bean加载机制详解

    这篇文章主要介绍了SpringMvc中的Bean加载机制详解,在Spring MVC中,Bean的作用主要是处理应用程序的业务逻辑和数据,例如,一个用户管理应用程序的Bean可能包括UserService、UserDao和UserController等,需要的朋友可以参考下
    2023-12-12
  • SpringBoot+Mybatis plus实现多数据源整合的实践

    SpringBoot+Mybatis plus实现多数据源整合的实践

    本文主要介绍了SpringBoot+Mybatis plus实现多数据源整合的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Maven的配置文件pom.xml详解(含常用plugin)

    Maven的配置文件pom.xml详解(含常用plugin)

    pom.xml是Maven项目的核心配置文件,它是 项目对象模型 - Project Object Model(POM)的缩写,本文我们将全面解析pom.xml,了解其结构和属性,以及如何使用它来管理项目,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • Spring Cloud引入Eureka组件,完善服务治理

    Spring Cloud引入Eureka组件,完善服务治理

    这篇文章主要介绍了Spring Cloud引入Eureka组件,完善服务治理的过程详解,帮助大家更好的理解和使用spring cloud,感兴趣的朋友可以了解下
    2021-02-02
  • OpenJDK源码调试图文教程

    OpenJDK源码调试图文教程

    这篇文章主要介绍了OpenJDK源码调试,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 使用Jackson来实现Java对象与JSON的相互转换的教程

    使用Jackson来实现Java对象与JSON的相互转换的教程

    这篇文章主要介绍了使用Jackson来实现Java对象与JSON的互相转换的教程,文中罗列了3中Jackson的使用方式,需要的朋友可以参考下
    2016-01-01
  • 详解SpringBoot2 使用Spring Session集群

    详解SpringBoot2 使用Spring Session集群

    这篇文章主要介绍了SpringBoot2 使用Spring Session集群,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-04-04
  • Java实现代码块耗时测算工具类

    Java实现代码块耗时测算工具类

    这篇文章主要为大家介绍了如何利用Java语言编写一个工具类,用来测算代码块的耗时,同时还能显示进度,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-05-05
  • Java的内存分配与回收策略详解

    Java的内存分配与回收策略详解

    这篇文章主要介绍了Java的内存分配与回收策略详解,对象的内存分配,就是在堆上分配,对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定,取决于当前使用的垃圾收集器组合以及相关的参数配置,需要的朋友可以参考下
    2023-08-08
  • 微服务框架FEIGN使用常见问题分析

    微服务框架FEIGN使用常见问题分析

    这篇文章主要为大家介绍了微服务框架FEIGN常见问题分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论