如何处理null

怎样做才能避免不期而至的NullPointerException呢?通常,可以在需要的地方添加null的检查(过于激进的防御式检查甚至会在不太需要的地方添加检测代码),并且添加的方式往往各有不同。

null-安全的第一种尝试:深层质疑

“深层质疑”,原因是它不断重复着一种模式:每次不确定一个变量是否为null时,都需要添加一个进一步嵌套的if块,也增加了代码缩进的层数。很明显,这种方式不具备扩展性,同时还牺牲了代码的可读性。

null-安全的第二种尝试:过多的退出语句

第二种尝试中,试图避免深层递归的if语句块,采用了一种不同的策略:每次遭遇null变量,都返回一个字符串常量“Unknown”。然而,这种方案远非理想,现在这个方法有了四个截然不同的退出点,使得代码的维护异常艰难。

使用Optional获取car的Insurance名称

汲取Haskell和Scala的灵感,Java 8中引入了一个新的类java.util.Optional<T>。这是一个封装Optional值的类。

public String getCarInsuranceName(Optional<Person> person){
return person.flatMap(Person::getCar)
.flatMap(Car::getInsurance)
.map(Insurance::getName)
.orElse("Unknown");//如果Optional的结果值为空,设置默认值
}

创建Optional对象

1. 声明一个空的Optional

可以通过静态工厂方法Optional.empty,创建一个空的Optional对象:

Optional<Car> optCar = Optional.empty();

2. 依据一个非空值创建Optional

还可以使用静态工厂方法Optional.of,依据一个非空值创建一个Optional对象:

如果car是一个null,这段代码会立即抛出一个NullPointerException,而不是等到试图访问car的属性值时才返回一个错误。

Optional<Car> optCar = Optional.of(car);

3. 可接受null的Optiona

使用静态工厂方法Optional.ofNullable,可以创建一个允许null值的Optional对象:

如果car是null,那么得到的Optional对象就是个空对象。

Optional<Car> optCar = Optional.ofNullable(car);

Optional类的方法

•null引用在历史上被引入到程序设计语言中,目的是为了表示变量值的缺失。

•Java 8中引入了一个新的类java.util.Optional<T>,对存在或缺失的变量值进行建模。

•可以使用静态工厂方法Optional.empty、Optional.of以及Optional.ofNullable创建Optional对象。

•Optional类支持多种方法,比如map、flatMap、filter,它们在概念上与Stream类中对应的方法十分相似。

•使用Optional会迫使更积极地解引用Optional对象,以应对变量值缺失的问题,最终,能更有效地防止代码中出现不期而至的空指针异常。

•使用Optional能帮助设计更好的API,用户只需要阅读方法签名,就能了解该方法是否接受一个Optional类型的值。

附:类代码

public class Person {
private Car car; public Car getCar() {
return car;
}
} public class Car {
private Insurance insurance; public Insurance getInsurance() {
return insurance;
}
} public class Insurance {
private String name; public String getName() {
return name;
}
}

附:使用Optional重新定义Person/Car/Insurance的数据模型

public class Person {
private Optional<Car> car;//人可能有车,也可能没有车,因此将这个字段声明为Optional public Optional<Car> getCar() {
return car;
}
} public class Car {
private Optional<Insurance> insurance;//车可能进行了保险,也可能没有保险,所以将这个字段声明为Optional public Optional<Insurance> getInsurance() {
return insurance;
}
} public class Insurance {
private String name;//保险公司必须有名字 public String getName() {
return name;
}
}

文章来源:java8实战 第十章

java8 用Optional取代null的更多相关文章

  1. 用optional取代null

    Java8引入了java.util.Optional<T>,它是一个封装的Optional值的类.变量存在时,Optional类只是对类简单封装.变量不存在时,缺失的值会被建模成一个空的O ...

  2. 《Java 8 in Action》Chapter 10:用Optional取代null

    1965年,英国一位名为Tony Hoare的计算机科学家在设计ALGOL W语言时提出了null引用的想法.ALGOL W是第一批在堆上分配记录的类型语言之一.Hoare选择null引用这种方式,& ...

  3. Java 8 (9) Optional取代null

    NullPointerException,大家应该都见过.这是Tony Hoare在设计ALGOL W语言时提出的null引用的想法,他的设计初衷是想通过编译器的自动检测机制,确保所有使用引用的地方都 ...

  4. Java8之Optional类

    写在前头 今天再看阿里的Java开发手册,里面异常处理第10条提到这样一个建议. [推荐]防止 NPE ,是程序员的基本修养,注意 NPE 产生的场景:1 ) 返回类型为基本数据类型,return 包 ...

  5. Java8的Optional:如何干掉空指针?

    目录 Optional概述 Optional简单案例 Optional的主要方法 参考阅读 Optional概述 Optional 是个容器:它可以保存类型T的value,或者仅仅保存null.Opt ...

  6. JDK8新特性:使用Optional避免null导致的NullPointerException

    空指针异常是导致Java应用程序失败的最常见原因.以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写 ...

  7. Java8:使用 Optional 处理 null

    写过 Java 程序的同学,一般都遇到过 NullPointerException :) —— 为了不抛出这个异常,我们便会写如下的代码: User user = getUserById(id); i ...

  8. Java8之使用Optional进行Null处理

    Optional类这是Java 8新增的一个类,用以解决程序中常见的NullPointerException异常问题,本篇文章将详细介绍Optional类,以及如何用它消除代码中的null检查. 1. ...

  9. java8中optional和.stream().map()

    使用optional的好处:是一个可以包含或不可以包含非空值的容器对象,更加友好的处理程序中的空对象. Optional<T>有方法 isPresent() 和 get() 是用来检查其包 ...

随机推荐

  1. NGINX状态模块的使用

    nginx状态模块可以用来查看当前nginx服务器的并发量和总的请求数 启用nginx的状态模块 状态模块需要在编译安装的时候启用. 1.下载nginx源码包 2.安装nginx并启用模块 3.修改n ...

  2. Kotlin属性委托系统总结与提供委托详解

    属性委托总结回顾: 在前三次已经将Kotlin委托相关的知识点进行了完整的学习了,具体博文如下: https://www.cnblogs.com/webor2006/p/11369019.html h ...

  3. Linux下安装Fiddler

    1.首先,你要有个Mono环境,在Ubuntu环境下安装很简单,输入: sudo apt-get install mono-complete 2.下载一个最新的Fiddler for Mono版本,下 ...

  4. websocket简单样例

    服务端 var server = require('ws').Server; }); serv.on('connection',function(socket){ socket.send('hello ...

  5. tensorflow API _ 5 (tensorflow.summary)

    tensorflow的可视化是使用summary和tensorboard合作完成的. 基本用法 首先明确一点,summary也是op. 输出网络结构 with tf.Session() as sess ...

  6. sql server 能按照自己规定的字段顺序展示

    工作中遇到,需要把sql 查询的按照指定的顺序显示 select plantname,cc_type,all_qty from VIEW_TEMP_DAY_CVT_CAP a where a.docd ...

  7. Linux 重启 PHP-FPM 命令

    1. 停止命令 pkill php-fpm 2.重启或启动命令 php-fpm -R

  8. Mysql 多表连接查询 inner join 和 outer join 的使用

    JOIN的含义就如英文单词“join”一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. 首先先列举本篇用到的分类(内连接,外连接,交 ...

  9. Hdu 3037 Saving Beans(Lucus定理+乘法逆元)

    Saving Beans Time Limit: 3000 MS Memory Limit: 32768 K Problem Description Although winter is far aw ...

  10. 50、Spark Streaming实时wordcount程序开发

    一.java版本 package cn.spark.study.streaming; import java.util.Arrays; import org.apache.spark.SparkCon ...