详解Spring的StringUtils踩坑记录
起因
最近在写CRUD的时候,发现有个分页的VO写的健壮性比较差,一时手痒改了一下,没想到改了之后好几个功能都出现了问题。
原VO关键代码如下:
publicclassPageVoimplementsSerializable{ //...省略所有无关代码 Mapquery }
这个VO是用于从前端分页查询时传参,而query是用于传递查询条件的(这里不讨论用Map传参是否合理)。当前端无查询条件时则会导致query为null,如果不注意容易出现NPE。
所以我就改造成下面这样了。
publicclassPageVoimplementsSerializable{ //...省略所有无关代码 Mapquery=newHashMap<> }
但是没想到就是这么简单的改造居然都翻车(・ε・`)
没办法,只好去排查问题。
发现问题
想过很多种原因,但是我真没想到居然是因为这样(/‵Д′)/~╧╧,不多说了,问题关键代码如下:
if(StringUtils.isEmpty(page.getQuery())){ //省略处理逻辑 }
居然用StringUtils去判断一个Map是否为空,好歹也换个CollectionUtils啊(╬ ̄皿 ̄)凸
虽然是前人挖坑,但是为什么Spring的`StringUtils居然设计成支持Object入参呢o_o....
想了一下,还是去看看源码吧
源码分析
StringUtils的isEmpty()方法源码超级简单,三行代码搞定(其实严格来说就一行代码):
publicstaticbooleanisEmpty(@NullableObjectstr){ return(str==null||"".equals(str)); }
既然我的Map对象不为null,那么问题应该是因为String的equals()方法。不多说,继续跟踪源码
publicbooleanequals(ObjectanObject){ if(this==anObject){ returntrue; } //问题出在这里 if(anObjectinstanceofString){ StringanotherString=(String)anObject; intn=value.length; if(n==anotherString.value.length){ charv1[]=value; charv2[]=anotherString.value; inti=0; while(n--!=0){ if(v1[i]!=v2[i]) returnfalse; i++; } returntrue; } } returnfalse; }
这个equals()方法的逻辑很简单
- 入参为null则返回true
- 入参不为String类型返回false
- 入参对象和this对象都为String就比较它们内置的char[]数组长度和每个char元素是否相同,满足则返回true,否则返回false
而我的问题就是由第二点引起的,因为类型不相同┴─┴︵╰(‵□′╰)
教训总结
- 不建议使用Spring的StringUtils的isEmpty()对非String类型的对象判空。(这里建议换成apachecommon的StringUtils或者GoogleGuava的Strings,这两个工具包都是类型强约束的)
- 无论是修改哪处的代码都最好检查一下引用,避免修复小问题引出大问题
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。