先假设一个场景。如下所示

 public class Person {

     private String name;

     public Person() {
} public Person(String name) {
this.name = name;
} public String getName() {
return name;
}
}

  我们有一个Person类,有一个属性是name。有如下代码:

 public static void main(String[] args) {
Person person = new Person(); String name = person.getName(); if (name.equals("Jackson")) {
System.out.println("My name is Jackson!");
}
}

  我们判断获取person的name,然后判断person的name是不是Jackson。因为person的name为null,所以name.equals("Jackson")这段代码会报空指针的异常。

  我们有多种方式来处理空指针的异常,一种是我们考察我们的业务逻辑,当需要返回一个null值时返回一个有意义的NullObject。例如空字符串对应返回字符串的情况,空列表对应返回list的情况,对一些特殊的对象,可以根据不同的业务逻辑创建一些Null对象。参考《Effictive Java》第43条,《重构》9.7节。

  对于我们的例子,当name为null时,getName方法返回一个""字符串。当接下来取出name来进行操作时就不会出现空指针的异常。

 public String getName() {
if (name == null) {
return "";
} else {
return name;
}
}

  另一种是在调用的时候判断是否为空,对于我们的例子,如下代码:

 if (name != null && name.equals("Jackson")){}

  通过判断name是否为空,若非空再判断name是否等于Jackson。通过这样的方式可以解决空指针异常的问题。

  但是两种方案都有一定的缺点,对于第一种方案,String和集合类型的Null对象很好确认,就是空字符串和空集合。但是对于一些特殊的对象,创建Null对象需要更多的步骤,更多的设计。总之就是两个字,麻烦。

  对于第二种方案,这个也是我们最常用的。但是这个方案有一个问题,就是经常会忘记判空。对于一个方法other.method(a, b),我们常常不会忘记对a和b进行判空,而对方法的返回值却经常忘记判空。而这个空指针异常是在运行时才会被发现,如果空指针的情况十分的罕见,那么很可能很长一段时间都不会发现这个异常。我常常碰到的一种情况是当数据库中存在脏数据的时候,正常的数据是不应该存在null的,但是即使是生产环境也很有可能混入一两个脏数据,很可能这罕见的脏数据导致程序报错。可能这个时候再去修复bug,代价比开发阶段高很多。

  为了优雅地处理null的情况,可以使用Java8的新特性Optional。API不说了,直接上代码

 public class Person {

     private String name;

     public Person() {
} public Person(String name) {
this.name = name;
} public Optional<String> getName() {
return Optional.ofNullable(name);
} public static void main(String[] args) {
Person person = new Person(); Optional<String> optionalName = person.getName();
if (optionalName.isPresent()) {
String name = optionalName.get();
System.out.println("My name is :" + name);
} else {
System.out.println("Who am I?");
}
}
}

  在getName里,我们由原来直接返回name,改成返回Optional<String>。通过Optional.ofNullable(T)静态方法,可以创建一个Optional对象。如果传入的对象是null,那么isPresent返回false,否则返回true。在上诉代码中,Person的name没有设置,optionalName.isPresent()返回的是false,所以打印出的应该是Who am I?

  从代码上看,这个和第二种方案,对对象判空的方法没有区别,都是先判断是否存在,然后再对对象进行操作。因为我们没法直接获取所需的对象,而是获得Optional对象,需要从Optional中获取我们需要的对象,因为不判空取不到所需对象,所以我们就不会忘了判空这步操作了。

使用Optional优雅处理null的更多相关文章

  1. Guava学习笔记(1):Optional优雅的使用null

    转自:http://www.cnblogs.com/peida/archive/2013/06/14/Guava_Optional.html 参考:[Google Guava] 1.1-使用和避免nu ...

  2. Optional优雅的使用null

    在我们学习和使用Guava的Optional之前,我们需要来了解一下Java中null.因为,只有我们深入的了解了null的相关知识,我们才能更加深入体会领悟到Guava的Optional设计和使用上 ...

  3. Guava学习笔记:Optional优雅的使用null

    在我们学习和使用Guava的Optional之前,我们需要来了解一下Java中null.因为,只有我们深入的了解了null的相关知识,我们才能更加深入体会领悟到Guava的Optional设计和使用上 ...

  4. Atitit. null错误的设计 使用Optional来处理null

    Atitit. null错误的设计 使用Optional来处理null 然后,我们再看看null还会引入什么问题. 看看下面这个代码: String address = person.getCount ...

  5. java8 Optional优雅非空判断

    java8 Optional优雅非空判断 import java.util.ArrayList;import java.util.List;import java.util.Optional; pub ...

  6. Google Guava之Optional优雅的使用null

    为什么使用optional 使用Optional<T>除了简化粗鲁的if(null == object).降低函数的复杂度.增加可读性之外,它是一种傻瓜式的防护,Optional<T ...

  7. Jdk14都要出了,还不能使用 Optional优雅的处理空指针?

    1. 前言 如果你没有处理过空指针,那么你不是一位真正的 Java 程序员. 空指针确实会产生很多问题,我们经常遇到空的引用,然后又想从这个空的引用上去获取其他的值,接着理所当然的碰到了 NullPo ...

  8. Java 中遇到null 和为空的情况,使用Optional来解决。

    Java 中遇到null 和为空的情况,使用Optional来解决 示例代码: package crazy; import java.util.Optional; class Company { pr ...

  9. JDK8 Java 中遇到null 和为空的情况,使用Optional来解决。

    空指针是我们最常见也最讨厌的异常,写过 Java 程序的同学,一般都遇到过 NullPointerException :) 初识null 详细可以参考[jdk 1.6 Java.lang.Null.P ...

随机推荐

  1. Robot Framework 读取控制面板安装的程序,判断某个程序是否已经安装

    wmic /output:D:\\DOAutomationTest\\automation_do_robotframework\\installList.txt product get name

  2. Java开发笔记(一百三十三)Swing的菜单

    传统的桌面程序基本是对某种类型的文件进行加工,例如Window自带的记事本用来读写文本文件,自带的画图程序用来查看和修改位图文件.为了方便用户切换各种操作,这些程序在窗口顶端放了一排菜单栏,单击菜单栏 ...

  3. 关于类视图选择继承APIView还是工具视图(ListAPIView、CreateAPIView等等)

    APIView使用方法,直接继承APIView,get或者post请求.方法很简单1.先获取到要操作的数据,然后把数据放到serializer中序列化或者反序列化,最后return返回值(记得.dat ...

  4. HTML-点击Div读取本地文件内容

    <!DOCTYPE html> <html> <div id="container" onclick="choosefile();" ...

  5. 关于goquery的“non-standard import”错误

    goquery运行缺包就用get github.com\andybalholm\cascadia下到gopath,然后出现“non-standard import”错误,说明github.com\an ...

  6. Ubuntu遇到apt-get update报错:"E: Could not get lock /var/lib/apt/lists/lock"

    sudo apt-get update报错:"E: Could not get lock /var/lib/apt/lists/lock" 出现此问题的原因可能是有另外一个程序在运 ...

  7. Scala 函数入门之默认参数和带名参数

    Scala 默认参数 在Scala中,有时我们调用某些函数时,不希望给出参数的具体值,而希望使用参数自身默认的值,此时就定义在定义函数时使用默认参数. def sayHello(firstName: ...

  8. grafana部署安装

    部署grafana 在prometheus& grafana server节点部署grafana服务. 1. 下载&安装 # 下载 [root@prometheus ~]# cd /u ...

  9. Spring Boot,Spring Security实现OAuth2 + JWT认证

    阅读此文,希望是对JWT以及OAuth2有一定了解的童鞋. JWT认证,提供了对称加密以及非对称的实现. 内容源码点我 涉及到源码中两个服务 spring-boot-oauth-jwt-server ...

  10. Spark 系列(一)—— Spark简介

    一.简介 Spark 于 2009 年诞生于加州大学伯克利分校 AMPLab,2013 年被捐赠给 Apache 软件基金会,2014 年 2 月成为 Apache 的顶级项目.相对于 MapRedu ...