1、StringUtils的null安全校验
在java项目编程,经常调试出现的问题就是空指针错误。出现错误的原因,是在程序执行的过程中莫名的出现了各种参数为空的错误,基于大型项目,功能,方法的来源,以及数量,我们并不能很好的鉴定在程序执行的过程中,哪些参数是问题参数。因此,在除去必定不为空的参数(静态变量,人为初始化值的数据),一般得,我们会使用if(str!=null&&str!="")作为判空校验。
这两种情况,java的jdk提供了一个对应的方法StringUtils.isEmpty(str).
StringUtils在commons-lang-2.2.jar包中:org.apache.commons.lang.StringUtils
StringUtils方法的操作对象是java.lang.String类型的对象,是JDK提供的String类型操作方法的补充,并且是null安全的(即如果输入参数String为null则不会抛出NullPointerException.
网上已有文字关于StringUtils的使用 包括isEmpty,isNotEmpty,isBlank,isNotBlank,这里摘录:
1. public static boolean isEmpty(String str)
判断某字符串是否为空,为空的标准是 str==null 或 str.length()==0
下面是示例:
StringUtils.isEmpty(null) = true
StringUtils.isEmpty("") = true
StringUtils.isEmpty(" ") = false //注意在 StringUtils 中空格作非空处理
StringUtils.isEmpty(" ") = false
StringUtils.isEmpty("bob") = false
StringUtils.isEmpty(" bob ") = false
2. public static boolean isNotEmpty(String str)
判断某字符串是否非空,等于 !isEmpty(String str)
下面是示例:
StringUtils.isNotEmpty(null) = false
StringUtils.isNotEmpty("") = false
StringUtils.isNotEmpty(" ") = true
StringUtils.isNotEmpty(" ") = true
StringUtils.isNotEmpty("bob") = true
StringUtils.isNotEmpty(" bob ") = true
3. public static boolean isBlank(String str)
判断某字符串是否为空或长度为0或由空白符(whitespace) 构成
下面是示例:
StringUtils.isBlank(null) = true
StringUtils.isBlank("") = true
StringUtils.isBlank(" ") = true
StringUtils.isBlank(" ") = true
StringUtils.isBlank("\t \n \f \r") = true //对于制表符、换行符、换页符和回车符
StringUtils.isBlank() //均识为空白符
StringUtils.isBlank("\b") = false //"\b"为单词边界符
StringUtils.isBlank("bob") = false
StringUtils.isBlank(" bob ") = false
4. public static boolean isNotBlank(String str)
判断某字符串是否不为空且长度不为0且不由空白符(whitespace) 构成,等于 !isBlank(String str)
下面是示例:
StringUtils.isNotBlank(null) = false
StringUtils.isNotBlank("") = false
StringUtils.isNotBlank(" ") = false
StringUtils.isNotBlank(" ") = false
StringUtils.isNotBlank("\t \n \f \r") = false
StringUtils.isNotBlank("\b") = true
StringUtils.isNotBlank("bob") = true
StringUtils.isNotBlank(" bob ") = true
可以看到isBlank比起isEmpy,涵盖的范围更广
另外,我们经常会对数据进行去空格的操作,以防止数据不为空但是没有数据的问题,旧时采用的str.trm()的方法。这种去空格的方法存在一个问题,如果str本来为null,调用trm()方法就会报错空指针。同样的,StringUtils也提供一个trim方法,可以解决这个问题。
5. public static String trim(String str)
去掉字符串两端的控制符(control characters, char <= 32) ,如果变为 null 或"",则返回 null
下面是示例:
StringUtils.trim(null) = null
StringUtils.trim("") = ""
StringUtils.trim(" ") = ""
StringUtils.trim(" \b \t \n \f \r ") = ""
StringUtils.trim(" \n\tss \b") = "ss"
StringUtils.trim(" d d dd ") = "d d dd"
StringUtils.trim("dd ") = "dd"
StringUtils.trim(" dd ") = "dd"
另外还有trim方法的两种变种,分别返回null/""
6. public static String trimToNull(String str)
去掉字符串两端的控制符(control characters, char <= 32) ,如果变为 null 或"",则返回 null
下面是示例:
StringUtils.trimToNull(null) = null
StringUtils.trimToNull("") = null
StringUtils.trimToNull(" ") = null
StringUtils.trimToNull(" \b \t \n \f \r ") = null
StringUtils.trimToNull(" \n\tss \b") = "ss"
StringUtils.trimToNull(" d d dd ") = "d d dd"
StringUtils.trimToNull("dd ") = "dd"
StringUtils.trimToNull(" dd ") = "dd"
7. public static String trimToEmpty(String str)
去掉字符串两端的控制符(control characters, char <= 32) ,如果变为 null 或 "" ,则返回 ""
下面是示例:
StringUtils.trimToEmpty(null) = ""
StringUtils.trimToEmpty("") = ""
StringUtils.trimToEmpty(" ") = ""
StringUtils.trimToEmpty(" \b \t \n \f \r ") = ""
StringUtils.trimToEmpty(" \n\tss \b") = "ss"
StringUtils.trimToEmpty(" d d dd ") = "d d dd"
StringUtils.trimToEmpty("dd ") = "dd"
StringUtils.trimToEmpty(" dd ") = "dd"
上面的trim是去掉空格,而strip去掉的是空白符
8. public static String strip(String str)
去掉字符串两端的空白符(whitespace) ,如果输入为 null 则返回 null
下面是示例(注意和 trim() 的区别):
StringUtils.strip(null) = null
StringUtils.strip("") = ""
StringUtils.strip(" ") = ""
StringUtils.strip(" \b \t \n \f \r ") = "\b"
StringUtils.strip(" \n\tss \b") = "ss \b"
StringUtils.strip(" d d dd ") = "d d dd"
StringUtils.strip("dd ") = "dd"
StringUtils.strip(" dd ") = "dd"
9. public static String stripToNull(String str)
去掉字符串两端的空白符(whitespace) ,如果变为 null 或"",则返回 null
下面是示例(注意和 trimToNull() 的区别):
StringUtils.stripToNull(null) = null
StringUtils.stripToNull("") = null
StringUtils.stripToNull(" ") = null
StringUtils.stripToNull(" \b \t \n \f \r ") = "\b"
StringUtils.stripToNull(" \n\tss \b") = "ss \b"
StringUtils.stripToNull(" d d dd ") = "d d dd"
StringUtils.stripToNull("dd ") = "dd"
StringUtils.stripToNull(" dd ") = "dd"
10. public static String stripToEmpty(String str)
去掉字符串两端的空白符(whitespace) ,如果变为 null 或"" ,则返回""
下面是示例(注意和 trimToEmpty() 的区别):
StringUtils.stripToNull(null) = ""
StringUtils.stripToNull("") = ""
StringUtils.stripToNull(" ") = ""
StringUtils.stripToNull(" \b \t \n \f \r ") = "\b"
StringUtils.stripToNull(" \n\tss \b") = "ss \b"
StringUtils.stripToNull(" d d dd ") = "d d dd"
StringUtils.stripToNull("dd ") = "dd"
StringUtils.stripToNull(" dd ") = "dd"
具体博客信息参考https://blog.youkuaiyun.com/weixin_42290280/article/details/82591161
因此总结一下,判空主要的两个函数isEmpt,isBlank,两个去空格操作trim,strip
2、str.equal("null")
上面所有的判空方法都能处理绝大多数的问题,不过存在一种字符串不为空确是空的情况,即str.equal("null") 出现这种问题的具体原因,暂时未确定,场景为:oracle数据库设置数据默认数据为空格时,更新其数据为null时,数据库会存下空格,在系统框架进行转换数据为实体类时,被赋予了“null”值,以至于在使用get方法时,判空校验后依旧出现了问题。个人猜测原因:系统框架在数据转换时的逻辑问题,由于是公司内部研究所提供的框架,并不知道其具体的内部逻辑,当然也不具备大众参考性,只是以后在校验数据库提醒,应当考虑这种问题。
20210218更新:通过研究系统的源代码,发现系统框架进行转换数据为实体类时,判空使用java原始的StringUtils的判空方法,导致如果数据库为空,前台不显示,但转换成字符,内置数据却成了字符串’null‘.而后在更新操作等过程中又重复写入到了数据库,导致数据错误,从而在运算等逻辑代码中报错。解决这个问题的方法是重构判空方法,引用jdk提供的StringUtils方法外,增加str.equal("null")的判定。