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

 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. Response的应用

    1.HttpServletResponse概述 service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServl ...

  2. Java开发笔记(一百一十七)AWT窗口

    前面介绍的所有Java代码,都只能通过日志观察运行情况,就算编译成class文件,也必须在命令行下面运行,这样的程序无疑只能给开发者做调试用,不能拿给一般人使用.因为普通用户早已习惯在窗口界面上操作, ...

  3. 长乐培训Day4

    T1 矩阵 题目 [题目描述] 从前有个 n×m 的矩阵,初始时每个位置均为 0.你需要依次执行 q 个操作,每个操作会指定一行或一列,然后将该行或该列的所有元素全部赋为一个相同的值. 输出操作完成后 ...

  4. 【IDEA使用技巧】(4) —— IDEA 构建Java Maven项目、导入Eclipse项目、多Module Maven项目

    1.IntelliJ IDEA构建Java Maven项目 1.1. IDEA构建Java Maven项目 ①选择Create New Project,选择创建Maven项目,并勾选Create fr ...

  5. PB对象Event ID说明

    原地址:https://www.cnblogs.com/nickflyrong/p/5973795.html Event ID 含义 内容浅析 event可以用pb自带的id,自动触发事件,而func ...

  6. mysql_重置密码

    # 修改编码 ```pythonshow variables like '%char%'; #查看当前使用的编码 1.打开配置文件: vim /etc/mysql/my.cnf 2.在[client] ...

  7. shell-基础2-字符串文本处理${}

    一.为什么使用${}引用变量 1.$a和${a}的效果与区别 因为个别特殊字符会影响正常引用,所以需要使用${}引用变量,加花括号是为了帮助解释器识别变量的边界 $a和${a}效果一样,当变量后面连接 ...

  8. java之结合代码理解synchronized关键字

    为了保证数据的一致性即实现线程的安全性,java虚拟机提供了同步和锁机制.synchronized关键字是最基本的互斥同步手段.除此之外,还可以使用java.util.concurrent包中的重入锁 ...

  9. python 标准库subprocess

    作者:Vamei 出处:http://www.cnblogs.com/vamei subprocess包主要功能是执行外部的命令和程序.subprocess的功能与shell类似.subprocess ...

  10. FreeRTOS计数型信号量

    API函数 //创建 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define xSemaphoreCreateCounting( uxMaxCount ...