千家信息网

怎么避免在Java代码中写大量的判空语句

发表于:2024-10-16 作者:千家信息网编辑
千家信息网最后更新 2024年10月16日,这篇文章主要介绍了怎么避免在Java代码中写大量的判空语句的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么避免在Java代码中写大量的判空语句文章都会有所收获,下面我们
千家信息网最后更新 2024年10月16日怎么避免在Java代码中写大量的判空语句

这篇文章主要介绍了怎么避免在Java代码中写大量的判空语句的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么避免在Java代码中写大量的判空语句文章都会有所收获,下面我们一起来看看吧。

有人说可以使用 JDK8提供的 Optional 来避免判空,但是用起来还是有些麻烦。

作者在日常工作中,封装了一个工具,可以链式调用对象成员而无需判空,相比原有的if null逻辑 和 JDK8提供的 Optional 更加优雅易用,在工程实践中大大提高了编码效率,也让代码更加的精准和优雅。

不优雅的判空调用

我想从事 Java 开发的小伙伴肯定有遇到过下面这种让人难受的判空逻辑:现在有一个User类,School 是它的成员变量

/*** @author Axin* @since 2020-09-20* @summary 一个User类定义 * (Ps:Data 是lombok组件提供的注解,简化了get set等等的约定代码)*/@Datapublic class User {    private String name;    private String gender;    private School school;    @Data    public static class School {        private String scName;        private String adress;    }}

现在想要获得School的成员变量 adress , 一般的处理方式:

public static void main(String[] args) {    User axin = new User();    User.School school = new User.School();    axin.setName("hello");    if (Objects.nonNull(axin) && Objects.nonNull(axin.getSchool())) {        User.School userSc = axin.getSchool();        System.out.println(userSc.getAdress());    }}

获取 adress 时要对 School 进行判空,虽然有些麻烦,到也能用,通过 JDK8 提供的 Optional 工具也是可以,但还是有些麻烦。

而下文的 OptionalBean 提供一种可以链式不断地调用成员变量而无需判空的方法,直接链式调用到你想要获取的目标变量,而无需担心空指针的问题。

链式调用成员变量

如果用了本文设计的工具 OptionalBean ,那么上述的调用可以简化成这样:

public static void main(String[] args) {    User axin = new User();    User.School school = new User.School();    axin.setName("hello");    // 1. 基本调用    String value1 = OptionalBean.ofNullable(axin)            .getBean(User::getSchool)            .getBean(User.School::getAdress).get();    System.out.println(value1);}

执行结果:

其中User的school变量为空,可以看到代码并没有空指针,而是返回了null。这个工具怎么实现的呢?

OptionalBean 工具

/*** @author Axin* @since 2020-09-10* @summary 链式调用 bean 中 value 的方法*/public final class OptionalBean {    private static final OptionalBean EMPTY = new OptionalBean<>();    private final T value;    private OptionalBean() {        this.value = null;    }    /**     * 空值会抛出空指针     * @param value     */    private OptionalBean(T value) {        this.value = Objects.requireNonNull(value);    }    /**     * 包装一个不能为空的 bean     * @param value     * @param      * @return     */    public static  OptionalBean of(T value) {        return new OptionalBean<>(value);    }    /**     * 包装一个可能为空的 bean     * @param value     * @param      * @return     */    public static  OptionalBean ofNullable(T value) {        return value == null ? empty() : of(value);    }    /**     * 取出具体的值     * @param fn     * @param      * @return     */    public T get() {        return Objects.isNull(value) ? null : value;    }    /**     * 取出一个可能为空的对象     * @param fn     * @param      * @return     */    public  OptionalBean getBean(Function fn) {        return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value));    }    /**     * 如果目标值为空 获取一个默认值     * @param other     * @return     */    public T orElse(T other) {        return value != null ? value : other;    }    /**     * 如果目标值为空 通过lambda表达式获取一个值     * @param other     * @return     */    public T orElseGet(Supplier other) {        return value != null ? value : other.get();    }    /**     * 如果目标值为空 抛出一个异常     * @param exceptionSupplier     * @param      * @return     * @throws X     */    public  T orElseThrow(Supplier exceptionSupplier) throws X {        if (value != null) {            return value;        } else {            throw exceptionSupplier.get();        }    }    public boolean isPresent() {        return value != null;    }    public void ifPresent(Consumer consumer) {        if (value != null)            consumer.accept(value);    }    @Override    public int hashCode() {        return Objects.hashCode(value);    }    /**     * 空值常量     * @param      * @return     */    public static OptionalBean empty() {        @SuppressWarnings("unchecked")        OptionalBean none = (OptionalBean) EMPTY;        return none;    }}

工具设计主要参考了 Optional 的实现,再加上对链式调用的扩展就是上述的OptionalBean。

getBean 其实是当变量为空时返回了一个 包装空值的 OptionalBean 对象,同时泛型的使用让工具更加易用。

使用手册

可以看到代码中也提供了和 Optional 一样的扩展方法,如 ifPresent()、orElse()等等:

public static void main(String[] args) {    User axin = new User();    User.School school = new User.School();    axin.setName("hello");    // 1. 基本调用    String value1 = OptionalBean.ofNullable(axin)            .getBean(User::getSchool)            .getBean(User.School::getAdress).get();    System.out.println(value1);    // 2. 扩展的 isPresent方法 用法与 Optional 一样    boolean present = OptionalBean.ofNullable(axin)            .getBean(User::getSchool)            .getBean(User.School::getAdress).isPresent();    System.out.println(present);    // 3. 扩展的 ifPresent 方法    OptionalBean.ofNullable(axin)            .getBean(User::getSchool)            .getBean(User.School::getAdress)            .ifPresent(adress -> System.out.println(String.format("地址存在:%s", adress)));    // 4. 扩展的 orElse    String value2 = OptionalBean.ofNullable(axin)            .getBean(User::getSchool)            .getBean(User.School::getAdress).orElse("家里蹲");    System.out.println(value2);    // 5. 扩展的 orElseThrow    try {        String value3 = OptionalBean.ofNullable(axin)                .getBean(User::getSchool)                .getBean(User.School::getAdress).orElseThrow(() -> new RuntimeException("空指针了"));    } catch (Exception e) {        System.out.println(e.getMessage());    }}

关于"怎么避免在Java代码中写大量的判空语句"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"怎么避免在Java代码中写大量的判空语句"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

代码 变量 工具 链式 成员 方法 空语句 空语 指针 目标 优雅 对象 目标值 知识 麻烦 包装 内容 篇文章 还是 逻辑 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 vspc软件开发 西藏网络安全保卫总队领导 山东大学网络安全专业郭峰 江西恩网络技术有限公司 复杂数学公式怎么数据库 专用服务器不能用 小说如何刷数据库 电视软件开发分层 互联网金融合金融科技 数据库技术与应用第二版严晖 威海app软件开发哪家做的好 2网络安全黑板报幼儿园 弱链的协议是加密数据库一致性 南京智慧工地软件开发 广州融联网络技术有限公司 河北网络技术信息便捷 启动服务器管理器出现错误 网络安全技术发展趋势 关注数据 世界互联网大会方正科技 任天堂什么软件开发 数据库实战视频教学 班信网络技术有限公司 椰子熊 学计算机网络技术有那些用 护苗网络安全课1.mp4 web服务器的配置管理和维护 服务器客户端数据库 北京智能消防软件开发多少钱 服务器人工智能管理平台 游戏本用于软件开发怎么样 第三方数据库是什么
0