对象空指针

没有人喜欢空指针异常 我们有办法摆脱它们吗?
也许 。

这篇文章中讨论了几种技术:

  • 可选类型(Java 8中的新增功能)
  • 对象类(旧的Java 7东西!)

Java 8中的可选类型

它是什么?

  • Java 8中引入的一种新类型(类)
  • 打算充当特定类型的对象或没有对象(空)的方案的“ 包装器

简而言之,它是处理空值的更好替代品警告 :起初可能不是很明显!)

基本用法

它是一种类型(一个类)–那么,如何创建它的实例?

只需在Optional类中使用三个静态方法。

public static Optional<String> stringOptional(String input) {return Optional.of(input);
}

简单明了–创建一个包含值的Optional包装器。 当心–如果值本身为null,将抛出NPE!

public static Optional<String> stringNullableOptional(String input) {if (!new Random().nextBoolean()) {input = null;}return Optional.ofNullable(input);
}

我个人认为好一点。 这里没有NPE的风险–如果输入为空,则将返回空的 Optional。

public static Optional<String> emptyOptional() {return Optional.empty();
}

如果您要有目的地返回“空”值。 'empty'并不意味着null

好了–使用/使用Optional怎么样?

public static void consumingOptional() {Optional<String> wrapped = Optional.of("aString");if (wrapped.isPresent()) {System.out.println("Got string - " + wrapped.get());}else {System.out.println("Gotcha !");}
}

一种简单的方法是检查Optional包装器是否具有实际值(使用isPresent方法)–这将使您想知道它是否比使用if(myObj!= null)好 。 不用担心,我也会解释这一点。

public static void consumingNullableOptional() {String input = null;if (new Random().nextBoolean()) {input = "iCanBeNull";}Optional<String> wrapped = Optional.ofNullable(input);System.out.println(wrapped.orElse("default"));
}

如果包装的值为null,则可以使用orElse来返回默认值,这很明显。 我们避免了在提取实际值之前调用ifPresent的明显冗长。

public static void consumingEmptyOptional() {String input = null;if (new Random().nextBoolean()) {input = "iCanBeNull";}Optional<String> wrapped = Optional.ofNullable(input);System.out.println(wrapped.orElseGet(() -> {return "defaultBySupplier";}));
}

我对此有些困惑。 为什么要使用两种单独的方法来实现相似的目标? orElseorElseGet很可能已被重载 (相同名称,不同参数)。

无论如何,这里唯一明显的区别是参数本身–您可以选择提供一个Lambda表达式来表示Supplier <T> (功能接口)的实例。

与常规的空值检查相比,使用Optional更好吗?

  • 总的来说,使用Optional的主要好处是能够清楚地表达您的意图 -简单地从方法中返回null会使消费者对是否是故意的存有疑问(当实际的NPE出现时)并且需要进一步自省javadocs(如果有)。 借助Optional,其水晶般清晰
  • 有以下几种方式可以完全避免NPE与可选-在上面的例子中所提到的,使用Optional.ofNullable(可选创建过程中)和否则容易orElseGet(可选消费过程中)从NPE上保护我们一起

另一个救星!

(以防您无法使用Java 8)

查看此代码段。

package com.abhirockzz.wordpress.npesaviors;import java.util.Map;
import java.util.Objects;public class UsingObjects {String getVal(Map<String, String> aMap, String key) {return aMap.containsKey(key) ? aMap.get(key) : null;}public static void main(String[] args) {UsingObjects obj = new UsingObjects();obj.getVal(null, "dummy");}
}

什么可能为空?

  • 地图对象
  • 执行搜索所依据的密钥
  • 在其上调用方法的实例

在这种情况下引发NPE时,我们永远无法确定什么是null

输入对象类

package com.abhirockzz.wordpress.npesaviors;import java.util.Map;
import java.util.Objects;public class UsingObjects {String getValSafe(Map<String, String> aMap, String key) {Map<String, String> safeMap = Objects.requireNonNull(aMap,"Map is null");String safeKey = Objects.requireNonNull(key, "Key is null");return safeMap.containsKey(safeKey) ? safeMap.get(safeKey) : null;}public static void main(String[] args) {UsingObjects obj = new UsingObjects();obj.getValSafe(null, "dummy");}
}

requireNonNull方法:

  • 如果其值不为null,则仅返回该值
  • 如果值为null,则将向NPE投掷指定的消息

为什么这比if(myObj!= null)更好

您将看到的堆栈跟踪将明显具有Objects.requireNonNull方法调用。 这以及您的自定义错误消息将帮助您更快地发现错误。 。 .IMO快得多!

您也可以编写用户定义的检查,例如,实施强制执行非空性的简单检查

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;public class RandomGist {public static <T> T requireNonEmpty(T object, Predicate<T> predicate, String msgToCaller){Objects.requireNonNull(object);Objects.requireNonNull(predicate);if (predicate.test(object)){throw new IllegalArgumentException(msgToCaller);}return object;}public static void main(String[] args) {//Usage 1: an empty string (intentional)String s = "";System.out.println(requireNonEmpty(Objects.requireNonNull(s), (s1) -> s1.isEmpty() , "My String is Empty!"));//Usage 2: an empty List (intentional)List list =  Collections.emptyList();System.out.println(requireNonEmpty(Objects.requireNonNull(list), (l) -> l.isEmpty(), "List is Empty!").size());//Usage 3: an empty User (intentional)User user = new User("");System.out.println(requireNonEmpty(Objects.requireNonNull(user), (u) -> u.getName().isEmpty(), "User is Empty!"));
}private static class User {private String name;public User(String name){this.name = name;}public String getName(){return name;}}
}

不要让NPE在错误的地方感到痛苦。 我们拥有一套不错的工具来更好地处理NPE或完全消除它们!

干杯!

翻译自: https://www.javacodegeeks.com/2014/09/optional-and-objects-null-pointer-saviours.html

对象空指针

对象空指针_可选和对象:空指针救星!相关推荐

  1. .net new一个类为什么报空指针_谈谈.NET对象生命周期

    不用程序员操心的堆 - 托管堆 程序在计算机上跑着,就难免会占用内存资源来存储在程序运行过程中的数据,我们按照内存资源的存取方式将内存划分为堆内存和栈内存. 栈内存通常使用的场景是:对存取速度要求较高 ...

  2. 声明对象 创建对象_流利的对象创建

    声明对象 创建对象 关于此主题的文章很多(绝大多数),但我只是想贡献我的两分钱,并写一篇简短的文章,介绍如何使用Java中的Fluent Object Creation模式或对象构建器实例化Value ...

  3. 并发加对象锁_通用并发对象池

    并发加对象锁 在本文中,我们将介绍如何在Java中创建对象池. 近年来,JVM的性能成倍增加,大多数类型的对象几乎都变得多余,从而提高了对象池的性能. 从本质上讲,对象的创建不再像以前那样昂贵. 但是 ...

  4. java 对象压缩_理解Java对象:要从内存布局及底层机制说起,话说....

    前言 大家好,又见面了,今天是JVM专题的第二篇文章,在上一篇文章中我们说了Java的类和对象在JVM中的存储方式,并使用HSDB进行佐证,没有看过上一篇文章的小伙伴可以点这里:< 这篇文章主要 ...

  5. java怎么打印对象内容_如何打印对象内容

    1. 一个最基本的例子 使用Logging框架写Log基本上就三个步骤 引入loggerg类和logger工厂类 声明logger 记录日志 下面看一个例子 //1. 引入slf4j接口的Logger ...

  6. 2019写给对象的话_写给对象的一段话暖心

    希望对您有帮助,谢谢 写给对象的一段话暖心 导读: 本文是关于写给对象的一段话暖心,如果觉得很不错, 欢迎点评和分享! 1 .有你,就是好!心事变很少:不烦也不恼.有你,就是好! 甜蜜心中绕: 幸福早 ...

  7. java新建对象校验_验证某个对象是否是一个mock对象或者一个spy对象

    C**f回复了y**4在课程中的问题:final和自动装配... v**g添加了笔记:James Gosl... c**k向课程作业中提交了代码 我**-向课程作业中提交了代码 2**9在课程中提出了 ...

  8. ossfs挂载百度对象存储_阿里云对象存储OSS挂载工具

    前言 宝塔面板里有类似服务9.9一个月,愿意花钱的大佬们也不会搜到我这篇文章 不想花钱的小伙伴们就仔细看看下面我这篇文章吧 科普:linux常用命令: ls 查看当前目录下文件 安装及配置 下载:安装 ...

  9. 2019写给对象的话_[想对对象说的一句情话]2019年最想对你说的十句情话

    1.请对我耐心一点,就像我对你一样. 2.你相信我,我就会感到很幸福了. 3.请不要忘记,我也有心,尽量不要让我太伤心,心碎了捡起来好麻烦. 4.我偶尔不听你的话是有原因的,因为你从来都没听过我的话, ...

最新文章

  1. Python测试框架pytest(01)简介、安装、快速入门
  2. 什么是机器人的五点校正法_样品定量检测怎样选择内标法和外标法!
  3. Noi2001食物链-并查集
  4. 音频处理基本概念及音频重采样
  5. vant自定义二级菜单
  6. 由获取子元素的方法find和children所获
  7. WPF的binding
  8. 【Tomcat】初次配置Tomcat的那些糟心事
  9. mysql服务器停止工作原理_MySQL服务器突然停止工作! - CentOS
  10. Android的第一天
  11. 《抉择与命运》读后感
  12. 修改样式_Word小技巧:如何设置样式 快速修改文本格式
  13. 机器学习基础(二十八) —— 数据规格化
  14. 十七、Oracle学习笔记:视图操作和表复制
  15. WIN10电脑端微信字体变模糊如何调节回来
  16. Linux 下恢复误删文件
  17. 朱松纯:初探计算机视觉三个源头兼谈人工智能
  18. 综述:基于影像基因组学的肺癌诊断治疗方法研究
  19. SB_5_瑞吉外卖_4_文件上传下载_菜品新增_菜品分页查询_菜品修改
  20. 【寒假每日一题】剪绳子(个人练习)详细题解+推导证明(第六天)

热门文章

  1. nssl1447-小智的糖果【dp】
  2. ssl1626-花店橱窗布置【日常dp】
  3. GYM101002C - Greetings!
  4. Nacos(十一)之NacosSync 介绍
  5. Oracle的分页实现
  6. Java IO: FileInputStream
  7. 漫画:什么是ConcurrentHashMap
  8. 优秀学生专栏——王浩
  9. 使用JDBCTemplate实现与Spring结合,方法公用 ——Spring配置(applicationContext.xml)
  10. MyBatis中的原理