欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Spring的StringUtils踩坑记录

程序员文章站 2022-06-12 11:06:01
起因 最近在写crud的时候,发现有个分页的vo写的健壮性比较差,一时手痒改了一下,没想到改了之后好几个功能都出现了问题。 原vo关键代码如下: public cla...

起因

最近在写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. 无论是修改哪处的代码都最好检查一下引用,避免修复小问题引出大问题

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