在我们日常的开发中,我们经常会遇到 NullPointerException。如何才能优雅的处理NPE?这里告诉大家一个较为流行的方法

java.util.Optional

使用Optional来修饰对象,表示这个对象可能为null。在使用时,就要加以注意,必须要考虑该值为null的场景。

使用Optional构建对象

        // 创建一个空的car
Optional<Car> car = Optional.empty(); // 使用of创建,of的值一定不能是null,否则赋值阶段就报 NullPointerException
/**
* if (obj == null)
* throw new NullPointerException();
*/
Car car1 = new Car();
Optional<Car> ocar1 = Optional.of(car1); // 创建一个可以为null的Optional,该方法支持car为null,但是会在用到car的地方抛出异常,但不是空指针异常。
Car car2 = new Car();
Optional<Car> ocar2 = Optional.ofNullable(car2);
System.out.println(ocar2.get());
Optional<Car> ocar22 = Optional.ofNullable(null);

获取Optional中的对象

  1. get: 这是最不安全的方法。如果变量存在就返回,不存在的话则会抛出NoSuchElementException的异常。所以,get()的使用场景一定是十分确定Optional修饰的值一定是有内容的,否则不建议使用。
        /**
* public T get() {
* if (value == null) {
* throw new NoSuchElementException("No value present");
* }
* return value;
* }
*/
String name = car.getInsurance().get().getName();
System.out.println(name);
  1. orElse: 作用和get一样,但是没有值时可以使用默认值
        /**
* public T orElse(T other) {
* return value != null ? value : other;
* }
*/
String orName = car.getInsurance().orElse(new Insurance()).getName();
System.out.println(orName);
  1. orElseGet: orElse的延时版本。只有当val为空时,才会创建defleat value
        /**
* public T orElseGet(Supplier<? extends T> supplier) {
* return value != null ? value : supplier.get();
* }
*/
String getElseName = car.getInsurance().orElseGet(Insurance::new).getName();
System.out.println("getElseName " + getElseName);
  1. orElseThrow: 和orElse类似,只是当value不存在时抛出异常
    public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
  1. ifPresent: 判断值存在之后再操作,不存在就不操作
        /**
* public void ifPresent(Consumer<? super T> action) {
* if (value != null) {
* action.accept(value);
* }
* }
*/
car.getInsurance().ifPresent(ins -> {
String pname = ins.getName();
System.out.println("inPresent " + pname);
});

Optional 中map和flatmap的差别

Optional<Optional<Car>> mCar = optionalPerson.map(Person::getCar);
Optional<Car> flatMapCap = optionalPerson.flatMap(Person::getCar);

map

    public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
// 返回值使用Optional包装
return Optional.ofNullable(mapper.apply(value));
}
}

flatMap

    public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
Optional<U> r = (Optional<U>) mapper.apply(value);
// 返回值没有包装,直接是Optional对象,只做了一次判null
return Objects.requireNonNull(r);
}
}

Java中的Optional的更多相关文章

  1. map和flatmap的区别+理解、学习与使用 Java 中的 Optional

    转自:map和flatmap的区别 对于stream,   两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...

  2. 理解、学习与使用 Java 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  3. 理解、学习与使用 JAVA 中的 OPTIONAL<转>

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  4. 理解、学习与使用 JAVA 中的 Optional【转载】

    这是一篇转载的文章.刚学java的时候看了好久这个Optional,但一直是懵的.今天又又遇到了,重新回来再看的时候,发现并没有那么难道那个. 转载的文章再开头处写了一个对于理解Optional很关键 ...

  5. JAVA 中的Optional (臭名昭著的空指针异常(NullPointerException))

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  6. 理解、学习与使用Java中的Optional

    从Java8 引入的一个很有趣的特性是Optional类.Optional类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异 ...

  7. Java中Optional类的使用

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  8. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  9. java中的tuple实现

    java中没有类似c#.scala中的tuple元组类,只能自己动手,丰衣足食了,见下面的代码: Tuple 抽象类 import java.util.Optional; /** * Tuple元组类 ...

随机推荐

  1. VGA设计(原理说明。Verilog代码实现,仿真结果)

    各类显示屏的显示原理大部分是利用人眼的视觉暂留效应.比如之前的数码管显示就是设计每个周期内各个小段按顺序显示,来达到显示一个数字的效果. VGA同理,显示屏在显示时是一个像素一个像素地显示,在人眼看来 ...

  2. NOI / 2.3基本算法之递归变递推-6262:流感传染

    OpenJudge - 6262:流感传染http://noi.openjudge.cn/ch0203/6262/ 6262:流感传染​​​​​​ 总时间限制: 1000ms 内存限制: 65536k ...

  3. Scanner练习

    练习1 键盘输入两个数字求和 public static void main(String[] args) { Scanner in = new Scanner(System.in); System. ...

  4. 1000-ms-maven相关问题

    一.Maven有哪些优点和缺点 优点如下: 简化了项目依赖管理: 易于上手,对于新手可能一个"mvn clean package"命令就可能满足他的工作 便于与持续集成工具(jen ...

  5. 物无定味适口者珍,Python3并发场景(CPU密集/IO密集)任务的并发方式的场景抉择(多线程threading/多进程multiprocessing/协程asyncio)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_221 一般情况下,大家对Python原生的并发/并行工作方式:进程.线程和协程的关系与区别都能讲清楚.甚至具体的对象名称.内置方法 ...

  6. 6.6 NOI 模拟

    \(T1\)括号序列 --那是,朝思夜想也未尝得到的自由 一个比较常见的转化,考虑如何判断前一段和后一段能够拼成一个合法的括号序列 充要条件: 前半部分,'('看为\(1\), ')'看为\(-1\) ...

  7. Chapter 02 - Let's Get Started(C#篇)

    详细解释,书上有哈.直接上代码和结果. Xcode下的自定义类 (通过new file-> cocoa class创建,保持和书中名字一样RandomController),自定义的fields ...

  8. [NCTF2019]True XML cookbook-1|XXE漏洞

    1.打开题目之后和做的上一道:https://www.cnblogs.com/upfine/p/16534940.html题目界面一样,查看源代码等未发现有用信息,界面如下: 2.那就先按原来那道题的 ...

  9. mongo数据同步的三种方案

    (一)直接复制data目录(需要停止源和目标的mongo服务)1.针对目标mongo服务已经存在,并正在运行的(mongo2-->mongo).执行步骤:(1).停止源/目标服务器的mongo服 ...

  10. 常用类--String

    一.String 1.1 String是不可变对象 String的底层是一个 char类型字符数组 String类是final修饰的,不能被继承,不能改变,但引用可以重新赋值 String采用的编码方 ...