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

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

3天内不再提示

善用Optional,告别NPE

京东云 来源:京东物流 王亚宁 作者:京东物流 王亚宁 2024-12-18 09:46 次阅读

作者:京东物流 王亚宁

1、NPE是什么?

NPE:NullPointerException(空指针异常)。可以说自Null的诞生以来它就让无数的程序员为之哀嚎,也是无数系统Bug的来源。托尼·霍尔(Tony Hoare),Null的发明者也表示过这是他十亿美元的错误。当程序试图在空引用(null)上调用方法或访问属性时,JVM会抛出NPE。例如:

String str = null;
int length = str.length(); // 这里会抛出NPE

1.1、NPE的常见原因

未初始化的对象:变量声明后未赋值,即默认为null。

方法返回null:方法可能返回一个对象或null,但调用者未进行null检查。

集合中的null元素:集合操作中插入了null,后续操作未处理。

多线程环境中的竞态条件:一个线程修改对象状态为null,另一个线程未及时检查。

1.2、NPE的影响

程序崩溃:未处理的NPE会导致程序终止,影响用户体验。

调试困难:NPE的堆栈信息可能不直观,定位问题源头耗时。

代码质量下降:频繁的NPE表明代码缺乏健壮的null处理机制。

2、Optional库介绍

为了应对NPE问题,Java 8引入了Optional类,它是一个容器对象,可以包含或不包含非null的值。通过Optional,开发者可以显式地表示一个值是可选的,从而强制进行null检查,减少NPE的发生。

2.1、Optional的基本用法

创建Optional对象
Optional< String > optional = Optional.of("Hello"); // 创建包含值的Optional
Optional< String > emptyOptional = Optional.empty(); // 创建空的Optional
Optional< String > nullableOptional = Optional.ofNullable(null); // 可以接受null
获取值
// 使用get()获取值,如果为空则抛出NoSuchElementException
optional.get();

// 使用orElse()提供默认值
String value = optional.orElse("Default");

// 使用orElseGet()提供默认值的Supplier
String value = optional.orElseGet(() -> "Default");

// 使用orElseThrow()在值为空时抛出异常
String value = optional.orElseThrow(() -> new IllegalArgumentException("Value is null"));
处理值
// 使用ifPresent()在值存在时执行操作
optional.ifPresent(val -> System.out.println(val));

// 使用map()转换值
Optional< Integer > lengthOptional = optional.map(String::length);

// 使用flatMap()处理嵌套的Optional
Optional< Optional< String >> nestedOptional = Optional.of(Optional.of("Nested"));
Optional< String > flatOptional = nestedOptional.flatMap(opt -> opt);

2.2、Optional的优势

明确的意图:方法返回Optional表明返回值可能为空,增强代码的可读性。

强制null检查:通过Optional的方法链,开发者必须处理可能的空值,减少遗漏。

函数式编程支持:与Lambda表达式和Stream API无缝结合,简化代码逻辑。

3、最佳实例示例

示例背景

假设有一个用户类User,包含一个地址类Address,而地址类中又包含城市信息City。在获取用户的城市名称时,存在多级空指针的风险。

public class User {
    private Address address;

    public Address getAddress() {
        return address;
    }
}

public class Address {
    private City city;

    public City getCity() {
        return city;
    }
}

public class City {
    private String name;

    public String getName() {
        return name;
    }
}

使用传统方式处理NPE

在没有使用Optional的情况下,获取城市名称可能需要多级null检查:

public String getUserCityName(User user) {
    if (user != null) {
        Address address = user.getAddress();
        if (address != null) {
            City city = address.getCity();
            if (city != null) {
                return city.getName();
            }
        }
    }
    return "Unknown";
}

上述代码层层嵌套,逻辑复杂,且易于遗漏某一级的null检查。并且代码也不容易阅读

使用Optional简化代码

利用Optional,可以将多级null检查转化为链式调用,代码更加简洁明了:

public String getUserCityName(Optional< User > userOptional) {
    return userOptional
            .map(User::getAddress)
            .map(Address::getCity)
            .map(City::getName)
            .orElse("Unknown");
}

另一个实例:处理方法返回值

假设有一个方法findUserById,可能返回一个User对象或null。使用Optional可以优雅地处理返回值。

public Optional< User > findUserById(String userId) {
    User user = userRepository.findById(userId); // 可能返回null
    return Optional.ofNullable(user);
}

调用方可以这样使用:

findUserById("12345")
    .map(User::getAddress)
    .map(Address::getCity)
    .map(City::getName)
    .ifPresent(cityName -> System.out.println("User city: " + cityName));

如果User不存在或其地址、城市信息为null,上述代码不会执行ifPresent中的打印操作,避免了NPE的风险。

总结

通过合理使用Java 8的Optional类,我们开发者可以有效减少NullPointerException的发生,提高代码的健壮性和可维护性。然而,Optional并非万能,需结合具体场景合理使用。掌握Optional的使用技巧和最佳实践,将有助于编写更安全、优雅的Java代码,真正做到“善用Optional,告别NPE”。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2964

    浏览量

    104684
  • null
    +关注

    关注

    0

    文章

    18

    浏览量

    3966
收藏 人收藏

    评论

    相关推荐

    JDK8新增的Optional类的常用方法

    一、摘要 NullPointerException,中文名: 空指针异常 ,也简称 NPE,是软件系统中最常见的错误异常之一。 很久以前 Google Guava 项目引入了 Optional 作为
    的头像 发表于 09-30 15:13 558次阅读

    善用户资料任务是不是有BUG?

    新人完善用户资料任务获取积分,现在发现不管你怎样完善都完成不了任务,是不是系统出现BUG了?
    发表于 10-06 09:11

    安装使用Qualcomm Snapdragon神经处理引擎(NPE) SDK

    本文介绍了如何开始使用Qualcomm®Snapdragon™神经处理引擎(NPE)SDK。 从干净的Ubuntu安装开始,本教程旨在为您提供安装依赖性的步骤,设置SDK工具,下载并准备一些示例
    发表于 09-25 16:48

    Snapdragon NPE SDK的环境配置

    上一篇博客简单描述了一下对Snapdragon NPE(Neural Processing Engine) SDK的初步了解,现在来看看配置环境,用Snapdragon NPE SDK进行
    发表于 09-27 16:50

    Snapdragon NPE SDK配置模型文件的转换和apk用例

    在上一篇博客中已经介绍了环境配置等,接下来接着看一下模型文件的转换和apk用例 首先是模型文件的创建,Snapdragon NPE SDK没有公共可用的模型文件,但是包含了一些脚本,这些脚本
    发表于 09-28 11:49

    【看动画,学知识】告别山寨机!手机音质测定,快,稳,准!

    告别山寨机!手机音质测定,快,稳,准!
    发表于 06-20 10:39

    2009美国国际塑料展/美国塑料展/NPE-----金彼岸

    2009国际塑料展览会(NPE2009)      
    发表于 05-05 12:05 676次阅读

    利用Ajax与ExtJS 改善用户体验

    本内容详细介绍了利用Ajax与ExtJS 改善用户体验
    发表于 05-24 15:21 24次下载
    利用Ajax与ExtJS 改<b class='flag-5'>善用</b>户体验

    JDK8 Optional类新特性

    Optional不是对null关键字的一种替代,而是对于null判定提供了一种更加优雅的实现。 NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从
    发表于 11-28 14:33 1771次阅读

    Facebook和Qualcomm合作优化Caffe2和Snapdragon NPE

    在正在进行的Facebook F8开发者大会上,Facebook和Qualcomm宣布携手合作,优化Caffe2和Snapdragon 神经处理引擎(NPE)软件框架。 Caffe是由伯克利
    发表于 09-18 19:16 168次阅读

    高通推出神经处理引擎(NPE)SDK,打造AI应用新优势

    我们最近推出的骁龙™神经处理引擎(NPE)SDK,强调了在设备端对时间要求较高的AI应用处理的重要性。例如,自动驾驶汽车可以即时作出决定——在检测到障碍物的同时加以识别和避免,而不是通过网络发送到云端服务器。
    发表于 03-17 09:22 1465次阅读

    JAVA8提供了Optional类来优化这种写法

    这种写法是比较丑陋的,为了避免上述丑陋的写法,让丑陋的设计变得优雅。JAVA8提供了Optional类来优化这种写法,接下来的正文部分进行详细说明
    的头像 发表于 04-24 15:18 1068次阅读

    认识Optional并使用

    的问题之一,那么我们今天就要尽可能的利用Java8的新特性 Optional来尽量简化代码同时高效处理NPE(Null Pointer Exception 空指针异常)。
    的头像 发表于 09-05 14:18 745次阅读

    是时候告别汽车照明离散解决方案了!

    是时候告别汽车照明离散解决方案了!
    发表于 11-01 08:26 0次下载
    是时候<b class='flag-5'>告别</b>汽车照明离散解决方案了!

    善用可靠且性价比高的隔离技术来应对高电压设计挑战

    电子发烧友网站提供《善用可靠且性价比高的隔离技术来应对高电压设计挑战》资料免费下载
    发表于 11-22 09:38 0次下载
    <b class='flag-5'>善用</b>可靠且性价比高的隔离技术来应对高电压设计挑战