0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何有效的处理空指针异常

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-09-30 10:25 次阅读

在编写 Java 程序的过程中,有一种异常几乎每个开发者都会遇到——空指针异常(NullPointerException)。这个问题可能会让一些新手菜鸟感到困扰,甚至一些经验丰富的开发者也会不时地遇到这个问题。

那么我们应该如何有效且优雅的处理空指针异常呢? 下面了不起将详细的介绍这个处理方案。

1、什么是空指针异常?

空指针异常在 Java 中是一个运行时错误,它发生在当我们试图访问一个 null 引用的成员时,例如调用一个 null 对象的方法或访问其字段。这种情况下,JVM 会抛出 NullPointerException。例如:

public class Main {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.length());  // 抛出 NullPointerException
    }
}

在这个例子中,我们试图调用 strlength() 方法,但是 strnull,所以 JVM 抛出了 NullPointerException

2、为什么会出现空指针异常?

在 Java 中,对象是通过引用来访问的。当我们声明一个对象变量时,只是创建了一个引用,并没有创建实际的对象。在使用对象之前,需要通过 new 关键字来创建实际的对象,将其赋给引用。但是,如果我们没有创建实际的对象,或者已经将对象置为 null,那么再试图使用这个引用,就会导致空指针异常。这是因为这个引用没有指向任何实际的对象,我们不能通过它来访问任何成员。

例如,下面的代码会导致空指针异常,因为我们试图访问 personname 字段,但是 personnull

public class Main {
    static class Person {
        String name;
    }

    public static void main(String[] args) {
        Person person = null;
        System.out.println(person.name);  // 抛出 NullPointerException
    }
}

3、如何预防空指针异常?

在我们开始处理空指针异常之前,我们需要首先学会如何预防它。以下是一些预防空指针异常的常见策略:

  • 使用 Objects.requireNonNull() 确认对象不为 null

Java 7 引入了一个很有用的工具类 Objects,它提供了一个 requireNonNull() 方法,这个方法可以用来检查一个对象是否为 null。如果对象是 null,它会抛出 NullPointerException。这可以帮助我们在早期发现和处理空指针问题。

例如:

import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        String str = null;
        str = Objects.requireNonNull(str, "str cannot be null");  // 抛出 NullPointerException
    }
}
  • 在方法中对参数进行非 null 校验

当我们编写一个方法并期望其参数不为 null 时,应当在方法开始处对参数进行非 null 校验。如果参数为 null,应当立即抛出 NullPointerExceptionIllegalArgumentException。这样可以尽早地发现问题,并避免错误的进一步传播。

例如:

public void process(String str) {
    if (str == null) {
        throw new IllegalArgumentException("str cannot be null");
    }

    // ...
}
  • 使用 Optional 类来更优雅地处理可能为 null 的情况

Java 8 引入了一个新的类 Optional,它是一个可以包含也可以不包含值的容器对象。Optional 提供了一种更优雅、更安全的方式来处理可能为 null 的情况,而无需显式地进行 null 检查。我们会在后面的部分详细讨论 Optional 的使用。

除了上述技术之外,也有一些通用的编程最佳实践可以帮助我们避免空指针异常。例如,我们应当尽量减少 null 的使用,尽量不要返回 null,可以考虑使用空对象或默认对象。在对输入参数进行处理时,我们应当总是假设输入可能为 null 并进行相应的处理。

4、如何捕获和处理空指针异常?

虽然我们已经知道了如何预防空指针异常,但是在某些情况下,我们可能还是需要捕获和处理这个异常。Java 提供了 try/catch 语句来捕获和处理异常,包括空指针异常。

下面是一个例子:

public class Main {
    public static void main(String[] args) {
        try {
            String str = null;
            System.out.println(str.length());  // 会抛出 NullPointerException
        } catch (NullPointerException e) {
            System.out.println("Caught a NullPointerException.");
            // 我们可以在这里处理异常,例如提供一个默认值
            // ...
        }
    }
}

在这个例子中,我们使用 try 块包围了可能抛出空指针异常的代码。如果 try 块中的代码抛出了空指针异常,那么控制流就会立即转到 catch 块,我们可以在 catch 块中处理这个异常。

虽然 try/catch 是一个强大的工具,但是我们应当谨慎使用它。不应该用 try/catch 来替代良好的编程实践和合理的 null 检查。过度使用 try/catch 可能会使代码变得混乱,难以阅读和维护,也可能会隐藏真正的问题。

5、Java 8 Optional 类的使用

如前所述,Java 8 引入了 Optional 类来帮助开发者更优雅地处理可能为 null 的情况。Optional是一个可以包含也可以不包含值的容器对象。当我们期望一个方法可能返回 null 时,可以考虑让它返回 Optional 对象,这样调用者就可以更方便地检查返回值是否为 null

下面是一个例子:

import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional< String > optional = getOptional();
        if (optional.isPresent()) {
            System.out.println(optional.get());
        } else {
            System.out.println("No value present");
        }
    }

    static Optional< String > getOptional() {
        // ...
        return Optional.empty();  // 返回一个不包含值的 Optional
    }
}

在这个例子中,getOptional() 方法返回一个 Optional。调用者可以使用 isPresent()方法来检查 Optional 是否包含值,然后使用 get() 方法来获取值。这样就可以避免了空指针异常。

6、编程最佳实践

下面是了不起给大家整理的处理空指针异常的最佳编程实践。

  • 对输入参数进行校验
    在处理方法参数之前,总是检查其是否为 null。如果方法不接受 null 参数,应该立即返回或抛出异常。
  • 尽量避免返回 null
    如果方法可能返回 null,考虑返回 Optional 类型,或者返回一个空对象或默认对象。这样可以避免调用者直接处理 null
  • 鼓励使用空对象或默认对象,而非 null
    空对象(也称为 Null 对象)或默认对象是一种设计模式,可以在没有数据的情况下提供默认的行为。使用空对象或默认对象可以简化代码,避免需要检查 null
  • 尽可能减少 null 的使用
    尽管 null 在 Java 中是不可避免的,但是我们应当尽量减少 null 的使用。过度使用 null 会导致代码难以理解和维护,并增加出错的可能性。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2904

    浏览量

    102994
  • 编程
    +关注

    关注

    88

    文章

    3440

    浏览量

    92400
  • 容器
    +关注

    关注

    0

    文章

    481

    浏览量

    21878
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70361
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66771
收藏 人收藏

    评论

    相关推荐

    指针指针的两个小点

    大家都知道指针的学习对于c语言学习来说可谓是至关重要的,下面我们来说一下在指针中两种比较特殊的关于指针的概念,野指针
    发表于 10-14 15:56

    函数指针的问题

    您好。我把函数指针作为参数传递给函数时遇到了一些问题。问题基本上是在一些循环下,函数指针的。最后检查代码和注释(1):(1)这是关键。如果我不使用这个句子,“数据”指针总是
    发表于 08-24 15:49

    【设计技巧】指针的使用注意事项:指针指针赋值、void *指针

    *)型。所以说,void类型指针是 传递参数的利器。 void型指针只能用于指针的传送,不能直接使用,我们传递完void类型指针后,当我们要具体使用它的时候,必须必须必须将该
    发表于 08-20 08:30

    Java异常体系级处理办法

    ;  CheckException:已检查异常,编译阶段必须处理;  几个经典的常见的RunTimeException如下:指针NullPointerException;数组下标越界
    发表于 01-05 17:48

    单片机的异常处理

    的返回地址,错误是否发生在异常处理中,以及EXC_RETURN的值是否被异常破坏等。另外,当前的寄存器值也可以提供有助于定位错误原因的各种信息,除了当前栈指针的值,当前的链接寄存器的值
    发表于 10-29 13:36

    DevEco Studio打开历史工程报指针错误怎么解决?

    DevEco Studio打开历史工程报指针错误
    发表于 04-12 11:48

    关于ARM的PC指针功能与异常返回处理介绍

    sp!, {pc} (2)当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断。程序计数器r15(PC):PC是有读写限制的。当没有超过读取限制的时候,读
    发表于 05-13 09:41

    DevEco Studio打开历史工程报指针错误是为什么?

    DevEcoStudio打开历史工程报指针错误
    发表于 06-10 10:21

    为什么程序中会出现指针?

    为什么程序中会出现指针
    发表于 10-10 07:25

    java异常处理的设计与重构

    在程序设计中,进行异常处理是非常关键和重要的一部分。一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度。试想一下,如果一个项目从头到尾没有考虑过
    发表于 09-27 15:40 1次下载
    java<b class='flag-5'>异常</b><b class='flag-5'>处理</b>的设计与重构

    指针变量, 位带指针 ,LSB最低有效位 ······

    指针变量,位带指针,LSB最低有效位······
    的头像 发表于 03-08 11:53 2091次阅读

    当ARM异常中断发生时的处理措施

    外部中断请求(IRQ) 当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。系统中个外设通过该
    的头像 发表于 08-27 14:21 2378次阅读

    处理器中异常和中断解决

    异常是能够引起程序流偏离正常流程的事件,当异常发生时,正在执行的程序就会被挂起,处理器转而执行一块与该事件相关的代码(异常处理)。事件可以是
    的头像 发表于 10-12 17:14 4275次阅读

    指针是什么

    ,口语中说的指针通常指的是指针变量。 1.2 内存 内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够
    的头像 发表于 11-24 15:50 1275次阅读
    <b class='flag-5'>指针</b>是什么

    bigdecimal转string类型避免空指针

    在Java中,BigDecimal是用于处理高精度数字计算的类。它提供了一种有效的方法来避免使用浮点数的精确度损失问题。然而,在将BigDecimal对象转换为String类型时,需要特别小心以避
    的头像 发表于 11-30 11:12 950次阅读