对象空指针_可选和对象:空指针救星!
对象空指针
没有人喜欢空指针异常 ! 我们有办法摆脱它们吗?
也许 。 。 。
这篇文章中讨论了几种技术:
- 可选类型(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";}));
}
我对此有些困惑。 为什么要使用两种单独的方法来实现相似的目标? orElse和orElseGet很可能已被重载 (相同名称,不同参数)。
无论如何,这里唯一明显的区别是参数本身–您可以选择提供一个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
对象空指针
对象空指针_可选和对象:空指针救星!相关推荐
- .net new一个类为什么报空指针_谈谈.NET对象生命周期
不用程序员操心的堆 - 托管堆 程序在计算机上跑着,就难免会占用内存资源来存储在程序运行过程中的数据,我们按照内存资源的存取方式将内存划分为堆内存和栈内存. 栈内存通常使用的场景是:对存取速度要求较高 ...
- 声明对象 创建对象_流利的对象创建
声明对象 创建对象 关于此主题的文章很多(绝大多数),但我只是想贡献我的两分钱,并写一篇简短的文章,介绍如何使用Java中的Fluent Object Creation模式或对象构建器实例化Value ...
- 并发加对象锁_通用并发对象池
并发加对象锁 在本文中,我们将介绍如何在Java中创建对象池. 近年来,JVM的性能成倍增加,大多数类型的对象几乎都变得多余,从而提高了对象池的性能. 从本质上讲,对象的创建不再像以前那样昂贵. 但是 ...
- java 对象压缩_理解Java对象:要从内存布局及底层机制说起,话说....
前言 大家好,又见面了,今天是JVM专题的第二篇文章,在上一篇文章中我们说了Java的类和对象在JVM中的存储方式,并使用HSDB进行佐证,没有看过上一篇文章的小伙伴可以点这里:< 这篇文章主要 ...
- java怎么打印对象内容_如何打印对象内容
1. 一个最基本的例子 使用Logging框架写Log基本上就三个步骤 引入loggerg类和logger工厂类 声明logger 记录日志 下面看一个例子 //1. 引入slf4j接口的Logger ...
- 2019写给对象的话_写给对象的一段话暖心
希望对您有帮助,谢谢 写给对象的一段话暖心 导读: 本文是关于写给对象的一段话暖心,如果觉得很不错, 欢迎点评和分享! 1 .有你,就是好!心事变很少:不烦也不恼.有你,就是好! 甜蜜心中绕: 幸福早 ...
- java新建对象校验_验证某个对象是否是一个mock对象或者一个spy对象
C**f回复了y**4在课程中的问题:final和自动装配... v**g添加了笔记:James Gosl... c**k向课程作业中提交了代码 我**-向课程作业中提交了代码 2**9在课程中提出了 ...
- ossfs挂载百度对象存储_阿里云对象存储OSS挂载工具
前言 宝塔面板里有类似服务9.9一个月,愿意花钱的大佬们也不会搜到我这篇文章 不想花钱的小伙伴们就仔细看看下面我这篇文章吧 科普:linux常用命令: ls 查看当前目录下文件 安装及配置 下载:安装 ...
- 2019写给对象的话_[想对对象说的一句情话]2019年最想对你说的十句情话
1.请对我耐心一点,就像我对你一样. 2.你相信我,我就会感到很幸福了. 3.请不要忘记,我也有心,尽量不要让我太伤心,心碎了捡起来好麻烦. 4.我偶尔不听你的话是有原因的,因为你从来都没听过我的话, ...
最新文章
- Python测试框架pytest(01)简介、安装、快速入门
- 什么是机器人的五点校正法_样品定量检测怎样选择内标法和外标法!
- Noi2001食物链-并查集
- 音频处理基本概念及音频重采样
- vant自定义二级菜单
- 由获取子元素的方法find和children所获
- WPF的binding
- 【Tomcat】初次配置Tomcat的那些糟心事
- mysql服务器停止工作原理_MySQL服务器突然停止工作! - CentOS
- Android的第一天
- 《抉择与命运》读后感
- 修改样式_Word小技巧:如何设置样式 快速修改文本格式
- 机器学习基础(二十八) —— 数据规格化
- 十七、Oracle学习笔记:视图操作和表复制
- WIN10电脑端微信字体变模糊如何调节回来
- Linux 下恢复误删文件
- 朱松纯:初探计算机视觉三个源头兼谈人工智能
- 综述:基于影像基因组学的肺癌诊断治疗方法研究
- SB_5_瑞吉外卖_4_文件上传下载_菜品新增_菜品分页查询_菜品修改
- 【寒假每日一题】剪绳子(个人练习)详细题解+推导证明(第六天)