目录
  • 一. 简介
  • 二. 产生原因
  • 三. 典型情况
    • 3.1 对空对象调用方法或访问属性
    • 3.2 数组元素为null
    • 3.3 参数为null
  • 四. 解决办法
    • 4.1 使用条件判断语句
    • 4.2 使用对象初始化语句
    • 4.3 使用Objects.requireNonNull()方法
    • 4.4 返回空数组
    • 4.5 使用Optional
    • 4.6 定位空指针异常
  • 五. 结语

    一. 简介

    你要问,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处理的资料请关注本网站其它相关文章!

    您可能感兴趣的文章:

    • 学习Java之自定义异常与NullPointerException的处理
    • java静态工具类注入service出现NullPointerException异常处理
    • java.lang.NullPointerException 如何处理空指针异常的实现
    • java.lang.NullPointerException异常的几种原因及解决方案
    • 无感NullPointerException的值相等判断方法
    • 解决java.lang.NullPointerException报错以及分析出现的几种原因