遇到空指针(npe)切莫慌 ✨ jdk 8中有妙招 ✨ 每日积累

简介: 遇到空指针(npe)切莫慌 ✨ jdk 8中有妙招 ✨ 每日积累

项目中空指针的烦恼


不管大大小小的项目,只要一个不注意,就会有java.lang.NullPointerException的异常抛出来,自己在测试的时候还好,但是线上项目一旦空指针切没有处理,那就问题大了。所以我们单测的开发好的需求的时候尽量吧所有的场景都测试一下。在 Java 8 之前,任何访问对象方法或属性的调用都可能导致 NullPointerException:,jdk8之后中有Class Optional这个类,能帮助我们更好的解决空指针问题。这个简单而强大的类有助于创建简单、可读性更强、比对应程序错误更少的程序。


api解释如下

可能包含或不包含非空值的容器对象。 如果一个值存在, isPresent()将返回true和get()将返回值。


提供依赖于存在或不存在包含值的其他方法,例如orElse() (如果值不存在则返回默认值)和ifPresent() (如果值存在则执行代码块)。


这是一个value-based课; 使用身份敏感的操作(包括引用相等(的==上的实例),标识哈希码,或同步) Optional可具有不可预测的结果,应当避免。


方法摘要

Modifier and Type

Method and Description
static <T> Optional<T> empty()返回一个空的 Optional实例。
boolean equals(Object obj)指示某个其他对象是否等于此可选项。
Optional<T> filter(Predicate<? super T> predicate)如果一个值存在,并且该值给定的谓词相匹配时,返回一个 Optional描述的值,否则返回一个空的 Optional 
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)如果一个值存在,应用提供的 Optional映射函数给它,返回该结果,否则返回一个空的 Optional 
T

get()如果 Optional中有一个值,返回值,否则抛出 NoSuchElementException

int

hashCode()返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。

void ifPresent(Consumer<? super T> consumer)如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。
boolean isPresent()返回 true如果存在值,否则为 false 
<U>Optional<U> map(Function<? super T,? extends U> mapper)如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 Optional结果的 Optional
static <T> Optional<T> of(T value)返回具有 Optional的当前非空值的Optional。
static <T> Optional<T> ofNullable(T value)返回一个 Optional指定值的Optional,如果非空,则返回一个空的 Optional 
T orElse(T other)返回值如果存在,否则返回 other 
T

orElseGet(Supplier<? extends T> other)返回值(如果存在),否则调用 other并返回该调用的结果。

<X extends Throwable>T orElseThrow(Supplier<? extends X> exceptionSupplier)返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。
String toString()返回此可选的非空字符串表示,适用于调试。


常用方法


创建Optional对象的方法:
 Optional.of(T t):创建一个Optional实例,t必须非空
 Optional.empty():创建一个空Optional实例
 Optional.ofNullable(T t):创建一个Optional实例,t可以为null
判断Optional对象中是否有对象:
 boolean isPresent():判断Optional容器中是否有对象
 void ifPresent(Consumer<? super T> consumer):如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 Optional结果的 Optional。
获取Optional容器中的对象:
 T get():如果调用对象包含值,返回该值,否则抛异常
 T orElse(T t1):如果调用容器中有值,则返回容器中的值,否则返回t1对象
 T orElseGet(Supplier<? extends T> other):如果有值则将其返回,否则返回由Supplier接口实现提供的对象
 T orElseThrow(Supplier<? extends X> exceptionSupplier):如果有值则返回,否则抛出由Supplier接口实现提供的异常


项目中可以组合使用的方法


如果项目中的一些参数不确定有值则可以这样使用


示例代码

import java.util.Optional;
import java.util.function.Supplier;
public class TestOptional {
    public static void main(String[] args) {
        UserTest userTest = new UserTest();
        userTest.setUserId("1");
        //isPresent():判断Optional容器中是否有对象
        String userName = userTest.getUserName().isPresent() == true ? userTest.getUserName().get() : "defaultName";
        System.out.println(userName);
        //orElse(T t1)
        System.out.println(userTest.getUserName().orElse("MrLi"));
        //orElseGet(Supplier<? extends T> other):如果有值则返回,没值则执行函数
        final String s = userTest.getUserName().orElseGet(new Supplier<String>() {
            @Override
            public String get() {
                return userTest.getUserName().orElse("Jhon") + "-test";
            }
        });
        System.out.println(s);
        //orElseThrow:在报错时可抛出异常供我们捕获进行处理
        try {
            userTest.getUserName().orElseThrow(() -> new NullPointerException());
        } catch (Throwable throwable) {
            //do something
            System.out.println("空指针异常");
        }
        //高级用法:嵌套类中的链式调用
        Employee employee = new Employee();
        employee.setUser(new Employee.User("MrWan"));
        String employeeName = Optional.ofNullable(employee)
                .flatMap(employeeTest -> employeeTest.getUser())
                .map(employeeTest -> {
                    employeeTest.setName("MrQing");
                    return employeeTest;
                }).get().getName().get();
        System.out.println(employeeName);
    }
}
class UserTest{
    private String userName;
    private String userId;
    //get()使用Optional<T>封装一下
    public Optional<String> getUserName() {
        return Optional.ofNullable(userName);
    }
    public Optional<String> getUserId() {
        return Optional.ofNullable(this.userId);
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    @Override
    public String toString() {
        return "UserTest{" +
                "userName='" + userName + '\'' +
                ", userId='" + userId + '\'' +
                '}';
    }
}
class Employee{
    private User user;
    public Optional<User> getUser() {
        return Optional.ofNullable(user);
    }
    public void setUser(User user) {
        this.user = user;
    }
    static class User{
        private String name;
        public User(String name) {
            this.name = name;
        }
        public Optional<String> getName() {
            return Optional.ofNullable(name);
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

运行结果

1.png

相关文章
|
数据采集 Java 数据库
大学里面抢课到底可行吗?我来给你彻底说明白
大学里面抢课到底可行吗?我来给你彻底说明白
|
9月前
|
机器学习/深度学习 人工智能
技术人的四大「造神」学习法,为啥就没人好好用呢?
技术人的四大「造神」学习法,为啥就没人好好用呢?
73 2
|
编译器 C++
《C++避坑神器·十八》运算符重载,小白也能看懂
《C++避坑神器·十八》运算符重载,小白也能看懂
61 0
|
算法 Java 程序员
你还不会递归?告别困惑,我来教你
递归是一种应用非常广泛的算法(或者编程技巧)。之后我们要讲的很多数据结构和算法的编码实现都要用到递归,比如DFS深度优先搜索、前中后序二叉树遍历等等。所以,搞懂递归非常重要,否则,后面复杂一些的数据结构和算法学起来就会比较吃力。
216 0
毕业两年了,又重学了一遍二叉树遍历的三种方式
毕业两年了,又重学了一遍二叉树遍历的三种方式
154 0
毕业两年了,又重学了一遍二叉树遍历的三种方式
|
测试技术
初级软件测试面试题怎么找?提供的这两个地方你肯定用得上
最近几年,随着电子产品和互联网的蓬勃发展,各类科技公司如雨后春笋般出现,而软件公司作为科技类公司中的重要组成部分,在这支互联网大军中也占据了重要一席。因而,负责软件问题质检的软件测试岗位也逐渐成了这几年炙手可热的就业岗位之一。
167 0
读者被问题代码折磨,鸭哥劝 NullPointerException 耗子尾汁!!!
说起来,鸭哥也算是身经百战的码农了,代码习惯和风格都是不错的。没想到,今天大意了没有闪,NullPointerException 就找上门来了。
223 0
读者被问题代码折磨,鸭哥劝 NullPointerException 耗子尾汁!!!
|
存储 编译器
懂了嘎嘎乱杀,但我赌你会懵——指针进阶终极版
正片开始👀 细化指针这一部分内容,现在着重把一些指针的运用情景搬出来康康,如果对指针盘的非常熟练了,或者指针还出于入门阶段的铁子请绕道(晕头警告) 直接给大家盘个套餐: 一维数组👏
懂了嘎嘎乱杀,但我赌你会懵——指针进阶终极版
|
SQL 数据库
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!(六)
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
132 0
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!(六)
|
SQL 关系型数据库 MySQL
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!(四)
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
132 0
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!(四)

相关实验场景

更多