java中Optional的使用

Java中optional对象的作用【转】 java中的optional是一个容器对象,它可以包含一个非空值,也可以为空。它的主要作用是在编写代码时避免空指针异常。 阅读详情

Optional的概念

java.util.Optional 是java8中引进的一个新的类,它可以对可能缺失的值进行建模,而不是直接将null赋值给变量。
它是用来规范我们开发的API,使其语义更加的明确,使用Optional修饰的对象,表示该对象可能为null。在一定程度上避免了空指针的问题。

Optional的由来

身为java程序员,空指针是最常见的问题了,它是在1965年被一位英国的计算机科学家 Tony Hoare开放的,他设计的初衷是因为采用null的这种引用方式,实现起来非常的容易。但是后来让众多开发人员痛苦不已,这也让他十分的后悔,自称为“价值百万的重大失误”。
每当我们对对象的格式进行检查,判断它的值是否是期望的格式时,却发现我们看到的并不是一个对象,而是一个空指针(java中没有指针,其实就是引用),这时就会抛出NullPointerExceptione的异常。
下面举个列子来验证该问题。

public class Person {
    private Car car;
    
    public Car getCar(){
        return car;
    }

}
class Car{

    private Insurance insurance;

    public Insurance getInsurance() {
        return insurance;
    }
}

class Insurance{

    private String name;
    
    public String getName() {
        return name;
    }
}

以上是要测试的三个类,现在要写一个方法,通过人员来获取保险

 public String getCarInsuranceName(Person person){
        return person.getCar().getInsurance().getName();
    }

上面的代码就会造成空指针的问题,因为有的人没有车,并且有的车没有保险。为了解决空指针的问题,我们常用的方法是防御式编程,可以进行如下的操作:

public String getCarInsuranceName(Person person){
        if (person!=null){
            Car car = person.getCar();
            if (car!=null){
                Insurance insurance = car.getInsurance();
                if (insurance!=null){
                    return insurance.getName();
                }
            }
        }
        return "Unknown";
    }

以上方法每次引用一个变量都会做一次null的检查,这样看似可以避免了空指针,却十分的冗余,因为当不确定一个变量是否为null时,都需要进行if的检查,这不仅增加了代码的可读性,还容易漏掉,并且维护起来也比较困难。
java引入空指针的危害:
1、它是很多问题的错误之源,它是目前开发中最典型的异常。
2、它会使代码膨胀,它会使我们的代码充满了深度嵌套的null检查,代码的可读性下降。
3、它自身是毫无意义的,null自身没有任何的语义,它表示以一种错误的方式对缺失变量的值建模。
4、它破坏了java的哲学,java一直避免引入指针的存在,而唯一的例外就是null指针。
5、它破坏了java的类型,null不属于任何类型,这也意味着它可以被赋值给任意引用类型的变量,我们将无法获取这个null值最初的类型是什么。
而Optional的出现可以让我们最大程度上规避上述问题。

Optional的使用

Optional入门教程

拿最上面的例子来讲,如果我们知道有的人没有车,那就不应该在Personal类内部声明Car的变量,因为Car类型存在,就说明一定会有Car类型的变量,而事实上并不是这样,所以使用Car类型不是一个明智的选择。我们可以使用Optional类对其进行包裹,当存在Car类型变量的时候就返回,当不存在的时候就返回一个空的Optional对象,它就像一个盒子,修饰的对象被放了进去。
除此之外,最重要的是,这就变的非常的明确,用Optional修饰,说明这里是允许变量缺失的。

public class Person {
    //有的人有车,也可能没有车,所以这里用Optional来修饰
    private Optional<Car> car;
    public Optional<Car> getCar(){
        return car;
    }

    public void setCar(Optional<Car> car) {
        this.car = car;
    }
}
class Car{

    //有的车上了保险,也有可能没有上,所以这里使用Optional修饰
    private Optional<Insurance> insurance;

    public Optional<Insurance> getInsurance() {
        return insurance;
    }

    public void setInsurance(Optional<Insurance> insurance) {
        this.insurance = insurance;
    }
}

class Insurance{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

当我们再次声明方法的时候,可以按如下方式操作:

public class OptionalTest {

    public static void main(String[] args) {
        Person person = new Person();
        Car car = new Car();
        Insurance insurance = new Insurance();
		
		//Optional.of()表示对象不能为null
        insurance.setName("insurance");
        car.setInsurance(Optional.of(insurance));
        person.setCar(Optional.of(car));

        String carInsuranceName = getCarInsuranceName(person);
    }


    public static String getCarInsuranceName(Person person) {
    	//可以通过get方法从Optional中取出值
        return person.getCar().get().getInsurance().get().getName();
    }

}

这样我们就不需要进行null的判断、检查,因为发生异常的时候,会直接在赋值为null的地方进行报错,而不会在调用方法的时候出现空指针。
在这里插入图片描述
需要注意的是:
Optional只是消除了进行null检查的逻辑,并快速定位问题,而不是消除每一个null的引用,相反,它的目标是帮助我们设置更优秀的API,让开发人员看到签名就知道这个变量的含义。
看到这里,有的同学觉得Optional只是形式上声明吗?不能规避空指针吗?答案是可以的,

创建Optional对象

创建Optional的方式有多种
1、声明一个空的Optional

	//使用Optional.empty()方法创建一个空的Car类型的Optional对象。
  Optional<Car> optionalCar = Optional.empty();

2、创建一个非空值的Optional,如果car为null的话,直接抛出空指针异常(参考上面的图片)。

 Car car = new Car();
 Optional<Car> car1 = Optional.of(car);

3、创建一个可以为null的Optional,该方法支持car为null,但是会在用到car的地方抛出异常,但不是空指针异常。

   Car car = new Car();
   Optional<Car> car2 = Optional.ofNullable(car);

在这里插入图片描述

从Optional对象中提取和转换值

虽然我们可以通过get方法从Optional中取出值,但是get方法在遭遇到空的Optional对象时仍然会抛出空指针异常,并没有解决我们的问题。所以我们需要按照约定的方式来使用它。

使用map从Optional对象中提取和转换值

就像stream流一样,这里也是可以通过通过map的方式从Optional中取出元素,map方法返回的也是一个Optional类型的对象,里面的值如果为null的话,可以使用orElse方法赋上自定义的值。

  Insurance insurance = new Insurance();
  insurance.setName("insurance");
  Optional<Insurance> optionalInsurance = Optional.ofNullable(insurance);
  String name = optionalInsurance.map(Insurance::getName).orElse("unKnown");

使用flatMap链接Optional对象

如果想要获取下面最终的值,我们通过map方法来尝试一下

public String getCarInsuranceName(Person person){
        return person.getCar().getInsurance().getName();
    }

当使用map的时候,代码如下:

 public static String getCarInsuranceName(Person person) {
        Optional<Person> optionalPerson = Optional.of(person);
        return optionalPerson.map(Person::getCar)
                .map(Car::getInsurance)
                .map(Insurance::getName)
                .orElse("unKnown");
    }

如上代码是编译不通过的,这里将person进行了Optional来修饰,才可以使用map方法,然后Person里面的Car对象也是用Optional来修饰的,所以使用map方法取出来的是一个用Optional<Optional< Car>>类型的对象,然后再对其使用map方法是行不通的,这里需要使用flatMap方法,就和之前的stream流一样,“将所有内容都放在最外面的容器里”。

   public static String getCarInsuranceName(Person person) {
        Optional<Person> optionalPerson = Optional.of(person);
        return optionalPerson.flatMap(Person::getCar)
                .flatMap(Car::getInsurance)
                .map(Insurance::getName)
                .orElse("unKnown");
    }

为了更清晰的展示map和flatMap的区别,大家可通过下面的demo来理解

        Person person = new Person();
        Optional<Person> optionalPerson = Optional.of(person);
        //map方法
        Optional<Optional<Car>> car1 = optionalPerson.map(Person::getCar);
        //flatMap方法
        Optional<Car> optionalCar1 = optionalPerson.flatMap(Person::getCar);

这里还需要注意的是:
如果对象没有使用Optional来修饰,直接使用get方法就可以拿到对象里面的Optional的值
如果对象使用Opional来修饰的话,就需要使用map方法。
在这里插入图片描述

Optional默认行为

get()

get()方法是最简单也是最不安全的方法,如果变量存在就返回,不存在的话则会抛出NoSuchElementException的异常。所以,get()的使用场景一定是十分确定Optional修饰的值一定是有内容的,否则不建议使用。使用的demo:

  Car car = new Car();
  Insurance insurance = new Insurance();
  car.setInsurance(Optional.of(insurance));
  //使用get来从Optional中取值。
  Insurance insurance1 = car.getInsurance().get();

orElse()

该方法相对于get()的好处在于当Optional对象中不存在则可以返回一个默认的值,使用的demo:

 Car car = new Car();
 Insurance insurance = new Insurance();
 car.setInsurance(Optional.of(insurance));
 //使用orElse来赋予默认的值
 Insurance insurance1 = car.getInsurance().orElse(new Insurance());

orElseGet()

该方法是orElse()方法的延迟调用版,当对象为空的时候才会产生默认值,它的性能相对于orElse()来说更好一些,建议使用该方法,下面是orElseGet()和orElse()的源码对比:

package java.util;
public final class Optional<T> {
    ...
	public T orElse(T other) { 
    	return this.value != null ? this.value : other;
	}
    public T orElseGet(Supplier<? extends T> supplier) {
        return this.value != null ? this.value : supplier.get();
	}
}

orElseThrow()

该方法和get方法很类似,当Optional修饰的对象为空的时候来抛出一个自己指定的异常类型。

ifPresent()

该方法对Optional修饰的对象进行判断,如果存在对象,则在进行某些操作,该方法里面放的是一个Consumer函数式接口,入参为T,void的类型的方法。

    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

使用demo:

 person.getCar().ifPresent(System.out::println);
Java中的Optional类详解 是 Java 8 引入的一个类,旨在解决空指针异常()的问题。它是一个容器对象,可以包含一个值或为空。通过使用Optional,可以避免显式的空值检测,从而提高代码的可读性和健壮性。Optional是 Java 8 引入的一个重要特性,旨在避免空指针异常,提高代码的可读性和健壮性。通过合理使用Optional,可以使代码更加简洁和优雅。希望本文的示例和讲解对您有所帮助,如果您在使用Optional时有任何疑问,欢迎随时交流探讨! 阅读详情

相关推荐

Index-TTS-1.5:多模态语音合成的技术演进与商业落地实践

本文深入探讨了Index-TTS-1.5在多模态语音合成领域的技术演进与商业落地。该模型基于GPT风格的自回归Transformer架构,通过优化条件编码器和引入字符-拼音混合建模,显著提升了语音生成的稳定性、精准度和真实感,实现了高质量的零样本语音克隆。文章还详细介绍了其云端体验、本地WebUI部署及ComfyUI集成等实战路径,并分析了其在虚拟数字人、个性化内容创作等商业场景中的应用潜力与挑战。

weixin_29098367的博客 402

Java中的Optional类

常用的Optional对象的方法

unravelmc的博客 1万+

基于STM32F334C8T6的四开关Buck-Boost双向DC-DC电源设计与实现(附源码、仿真与计算书)

本文详细介绍了基于STM32F334C8T6的四开关Buck-Boost双向DC-DC电源设计方案。该设计利用STM32的高分辨率定时器(HRTIM)实现精确PWM控制,支持Buck、Boost和Buck-Boost三种工作模式自动切换,具备双向能量流动能力。通过PSIM仿真和Mathcad计算书进行参数优化,实测效率达95.8%,适用于新能源系统和电池管理等场景。

www00的博客 528

详细分析Java中的Optional类以及应用场景

用开发的角度来讲,该类是 Java 8 中引入的一个用于处理可能为 null 的值的容器类。 它的设计目的是为了解决在代码中频繁出现的空指针异常问题。

码农研究僧的博客 1万+

计算机应用数学--第一次作业

中科大 计算机应用数学 第一次作业

一杯水果茶!足矣~ 1329

统计学习导论(ISLR) 第四章分类算法课后习题

统计学习导论(ISLR) 参考资料: The Elements of Statistical Learning An Introduction to Statistical Learning 统计学习导论(ISLR)(二):统计学习概述 统计学习导论(ISLR)(三):线性回归 统计学习导论(ISLR)(四):分类 ISLR统计学习导论之R语言应用(二):R语言基础 ISLR统计学习导论之R语言应用(三):线性回归R语言代码实战 ISLR统计学习导论之R语言应用(四):分类算法R语言代码实战 统计学习导论

阿里云专家博主、数据科学领域优质创作者、统计er在读 2万+

Java 8 Optional 详细用法

一、简介 Optional 是一个对象容器,具有以下两个特点:     提示用户要注意该对象有可能为null     简化if else代码 二、使用介绍 1. 创建:     Optional.empty(): 创建一个空的 Optional 实例     Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常           Optio...

旅行者 4万+

【推荐系统】推荐算法:冷启动-召回-粗排-精排-重排 解读

【推荐系统】推荐算法:冷启动-召回-粗排-精排-重排 解读

Danger的博客 3761

Java 中的Optional使用方法详解

在 Java 中,Optional 类是为了解决可能出现的 null 值问题,从而避免 NullPointerException。使用 Optional 可以优雅地处理 null 检查,使代码更简洁和安全。创建 Optional 可以通过 Optional.of(), Optional.ofNullable() 和 Optional.empty() 方法。检查值是否存在可以使用 isPresent() 或 JDK 11 引入的 isEmpty()。

科技改变人类,技术成就未来 5800

Codex 100个真实案例 - 用AI批量清洗Excel脏数据(10万行3分钟搞定)

每个做数据分析的人都被"脏数据"折磨过——空值、重复行、日期格式五花八门、手机号多一位少一位……手动清洗几千行就已经让人崩溃,更别提10万行了。本文将展示如何用 Codex 生成一套完整的 Python pandas 数据清洗工具,从读取Excel/CSV、识别脏数据、自动清洗、生成清洗报告,到可视化对比清洗前后的数据质量,全程自然语言驱动,10万行数据3分钟搞定!

yueyeguzhuo的专栏 88

2026年美赛数学建模竞赛 MCM B题:使用太空电梯系统建立月球殖民地 问题一 月球殖民地材料运输的三种场景建模 详细解题思路和代码

如果运输系统不能完美工作(例如,系绳摆动、火箭失败、电梯故障等),你的解决方案在多大程度上会发生变化?技术可行性:三种方案在技术上都是可行的,但挑战不同 经济性:混合方案在长期视角下最具成本效益 时间效率:并行运输可以显著缩短总建设时间环境影响:太空电梯的环境优势明显,混合方案可平衡需求风险分散:混合方案提供了天然的风险分散机制

YOLO 617

java中Optional使用

java中Optional使用 文章目录java中Optional使用一、简介二、使用2.1 创建2.2 取值2.2.1 get方法2.2.2 orElse方法2.2.3 orElseGet方法2.2.4 orElseThrow方法2.3 存在时执行2.4 存在时过滤2.5 存在时转换2.5.1 map方法2.5.2 flatMap方法 一、简介 Optional是jdk8引入的,用于处理java中的null。在实际使用,还是比较好用的,这里对常见用法进行介绍。 二、使用 2.1 创建 //创建空的Opti

panda-star的博客 1958

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Guava Optional 和 Java 8 optional

Null  上帝创造了男人,多年之后他老人家后悔了! Null的发明人同时也是快速排序的发明人表达对Null的忏悔称:“”这是个造成上亿美元损失的错误“。

lessisawesome 的专栏 6430

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java - Optional类

Optional 类是 Java 8 才引入的,Optional 是个容器,它可以保存类型 T 的值,或者仅仅保存 null。Optional 提供了很多方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。通过Optional提供的方法,如map、orElse等,可以更优雅地处理可能为空的对象,避免显式的null检查,使代码更简洁。文章介绍了Optional的创建、获取值的方法以及注意事项,如避免基础类型的Optional和合理使用orElse方法。方法描述empty。

gghhb12的博客 1355

Optional 详解 Java

Optional的使用详解 1、Optional介绍 Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。 Optional 类的引入很好的解决空指针异常。 2、构建Optional 构建一个Optional对象;方法有:empty( )、of( )、ofNullable( )

北 1万+

Java8中Optional详解

文章目录1.前言2.Optional介绍3.创建Optional3.1empty3.2of3.3ofNullable4.获取Optional的值4.1get()5.检查Optional是否有值5.1isPresent()5.2ifPresent()6.filter7.map8.flatMap9.返回默认值9.1orElse9.2orElseGet9.3orElseThrow10.orElse和or...

Life is for sharing的博客 3549

Java Optional使用

文章目录Optional一、Optional 简介二、创建 Optional 实例2.1 empty()方法2.2 of() 方法2.3 ofNullable() 方法三、Optional的使用3.1 访问 Optional 对象的值3.1.1 get() 方法3.1.2 isPresent()方法3.2 返回默认值3.2.1 orElse()方法3.2.2 orElseGet()方法3.2.3 orElse() 和 orElseGet() 的不同之处3.3 返回异常3.3.1 orElseThrow()

Samven_7的博客 4319

JAVA 8 Optional

Optional<T>对象是一种包装器对象,被当作一种更安全的方式,用来替代类型T的引用,用以解决空指值异常所带来的问题。

天书笔记 1234

java8中optional的使用

java8中optional的使用 ​ 我们在写java代码中,尤其是业务代码,如果一个类的组合以及级联关系过多时,很容易造成空指针异常,如下面一个例子: //人 public class Person { private Car car; public Car getCar() { return car; } } //车 public class Ca...

wangzhen的博客 3187

java8中的Optional

Optional类主要解决空指针异常NullPointerException。 Optional 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。 创建Optional 对象 1. 声明一个空的Optional 通过静态工厂方法Optional.empty()...

兴国-为梦想而战 1万+

【JAVA】Optional的使用

Optional是 Java 8 引入的一个非常重要的容器类,其主要目的是

qq_60755751的博客 841

​Java8 Optional用法 ​

在这之后,我们想要的是存储在Optional中的值,我们可以通过get()来获取它。不过,这样做可能很有诱惑力,如果对象为空,请避免与Option.empty()返回的实例的{==}比较。最后介绍的是新的 stream() 方法,它通过把实例转换为 Stream 对象,让你从广大的 Stream API 中受益。既然 getter 方法返回 String 值的 Optional,你可以在对 User 的 Optional 对象调用 flatMap() 时,用它作为参数。反之,返回false。

2301_76234376的博客 2046

JAVA - Optional的使用

目录前言Optional是Java 8 中引入的一个特性,其主要是为了解决臭名昭著的空指针异常(NullPointerException),其本质上是一个包含有可选值的包装类,意味着Optional既可以含有对象也可以为空。使用Optional的好处 - 优化代码 - 给判空操作提供一种标准的写法,强制要考虑空值的情况 具体应用 类方法

Maggieq8324的博客 2575

Java中Optional类的使用

从 Java 8 引入的一个很有趣的特性是Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异常。 本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。 Optional 是 Java 实现函数式编程的强劲一...

163

Java8之使用Optional

Java8之使用Optional 第十章 用Optional取代null 2、Optional 类入门 防止出现NullPointerException 原始代码-有个人,人有车,车有保险 public class Person { private Car car; public Car getCar() { return car; } } public c...

qimowei的博客 467
上一篇: java8新特性----Stream流使用
下一篇: idea如何解决jar包冲突
玉带林中挂
博客等级 码龄8年 264粉丝 167原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值