详解Spring的StringUtils踩坑记录

 更新时间:2020年01月10日 08:32:34   作者:Null  
这篇文章主要介绍了详解Spring的StringUtils踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

起因

最近在写CRUD的时候,发现有个分页的VO写的健壮性比较差,一时手痒改了一下,没想到改了之后好几个功能都出现了问题。

原VO关键代码如下:

public class PageVo implements Serializable{
  // ...省略所有无关代码
  Map<String, String> query
  
}

这个VO是用于从前端分页查询时传参,而query是用于传递查询条件的(这里不讨论用Map传参是否合理)。当前端无查询条件时则会导致query为null,如果不注意容易出现NPE。

所以我就改造成下面这样了。

public class PageVo implements Serializable{
  // ...省略所有无关代码
  Map<String, String> query=new HashMap<>
  
}

但是没想到就是这么简单的改造居然都翻车(・ε・`)

没办法,只好去排查问题。

发现问题

想过很多种原因,但是我真没想到居然是因为这样(/‵Д′)/~ ╧╧,不多说了,问题关键代码如下:

if (StringUtils.isEmpty(page.getQuery())) {
  // 省略处理逻辑
}

居然用StringUtils去判断一个Map是否为空,好歹也换个CollectionUtils啊(╬ ̄皿 ̄)凸

虽然是前人挖坑,但是为什么Spring的`StringUtils居然设计成支持Object入参呢o_o ....

想了一下,还是去看看源码吧

源码分析

StringUtils的isEmpty()方法源码超级简单,三行代码搞定(其实严格来说就一行代码):

public static boolean isEmpty(@Nullable Object str) {
  return (str == null || "".equals(str));
}

既然我的Map对象不为null,那么问题应该是因为String的equals()方法。不多说,继续跟踪源码

public boolean equals(Object anObject) {
    if (this == anObject) {
      return true;
    }
    // 问题出在这里
    if (anObject instanceof String) {
      String anotherString = (String)anObject;
      int n = value.length;
      if (n == anotherString.value.length) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = 0;
        while (n-- != 0) {
          if (v1[i] != v2[i])
            return false;
          i++;
        }
        return true;
      }
    }
    return false;
  }

这个equals()方法的逻辑很简单

  1. 入参为null则返回true
  2. 入参不为String类型返回false
  3. 入参对象和this对象都为String就比较它们内置的char[]数组长度和每个char元素是否相同,满足则返回true,否则返回false

而我的问题就是由第二点引起的,因为类型不相同┴─┴︵╰(‵□′╰)

教训总结

  1. 不建议使用Spring的StringUtils的isEmpty()对非String类型的对象判空。(这里建议换成apache common的StringUtils或者Google Guava的Strings,这两个工具包都是类型强约束的)
  2. 无论是修改哪处的代码都最好检查一下引用,避免修复小问题引出大问题

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 16进制显示字节流技巧分享

    16进制显示字节流技巧分享

    这篇文章主要介绍了16进制显示字节流的技巧分享,需要的朋友可以参考下
    2014-02-02
  • Spring Boot 项目设置网站图标的方法

    Spring Boot 项目设置网站图标的方法

    这篇文章主要介绍了Spring Boot 项目设置网站图标的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • Java实现在Word中嵌入多媒体(视频、音频)文件

    Java实现在Word中嵌入多媒体(视频、音频)文件

    这篇文章主要介绍了Java如何实现在Word中嵌入多媒体(视频、音频)文件,文中的示例代码讲解详细,对我们学习java有一定的帮助,感兴趣的同学可以了解一下
    2021-12-12
  • 详解如何在React中逃离闭包陷阱

    详解如何在React中逃离闭包陷阱

    众所周知,JavaScript 中的闭包(Closures)一定是这种语言最可怕的特性之一,另外它可能也是最隐蔽的语言特性之一,我们在编写 React 代码时经常会用到它,但是大多数时候我们甚至没有意识到这一点,本文小编将和大家一起深入探讨如何在React中逃离闭包陷阱
    2023-09-09
  • SpringBoot前后端交互、全局异常处理之后端异常信息抛到前端显示弹窗

    SpringBoot前后端交互、全局异常处理之后端异常信息抛到前端显示弹窗

    Spring Boot是一个用于构建独立的、基于生产级别的Spring应用程序的框架,下面这篇文章主要给大家介绍了关于SpringBoot前后端交互、全局异常处理之后端异常信息抛到前端显示弹窗的相关资料,需要的朋友可以参考下
    2024-08-08
  • Java流程控制之选择结构

    Java流程控制之选择结构

    这篇文章主要介绍了Java流程控制之选择结构,主要以if单选择结构、if双选择结构、if多选择结构、嵌套的if结构、switch多选择结构多种选择结构展开全文。需要的小伙伴可以参考一下
    2021-12-12
  • Java之String[] args含义及作用

    Java之String[] args含义及作用

    这篇文章主要介绍了Java之String[] args含义及作用,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法(报数据重复Duplicate entry的问题)

    Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法(报数据重复Duplicate entry的

    在开发中,我们经常会有逻辑删除和唯一索引同时使用的情况,但当使用mybatis plus时,如果同时使用逻辑删除和唯一索引,会报数据重复Duplicate entry的问题,如何解决这个问题呢,小编给大家分享Mybatis-Plus同时使用逻辑删除和唯一索引的问题及解决办法,一起看看吧
    2023-11-11
  • 超全面的SpringBoot面试题含答案

    超全面的SpringBoot面试题含答案

    这篇文章主要收录了44道面试中经常被问的SpringBoot问题,不管你是正在求职的新手还是已经工作很久的高手,这篇关于SpringBoot的面试题总结一定会让你有新的理解,让我们一起来看看吧
    2023-03-03
  • java实现员工工资管理系统

    java实现员工工资管理系统

    这篇文章主要为大家详细介绍了java实现员工工资管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论