一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
【日期】
2022/4/11
【问题】
今天,在和前端同事A对接接口的时候,发现前端传入空字符串,也能存入状态。(这里是把状态弄成一个公共方法,判断一个字符串不在这些字符串里)
例如:判断data是否有txt
/**
* 判断data是否有txt
*
* @Method: isTxtInDate
* @author: nanfangzhe
* @date: 2022年4月11日
* @param txt
* @param data
* @return boolean
*/
public static boolean isTxtInDate(String txt, String data) {
// return data.indexOf(txt) != -1;
}
但是,这里是存在问题的,如果传入空的字符串:"",长度为0;返回结果也是true,就会导致出错了!
如图:
【原因】
原因是:indexOf的源码里,字符串长度是0,会直接返回规则的Data数据的长度,而不是会返回-1;进而返回false。
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
【如何发现】
查看String.indexOf的源码
我们也来了解和分析一下indexOf()的原理,探索底层原理
这里就直接把理解和分析写在注释上了。(这里是直接复制最底层的indexOf的方法)
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount, int fromIndex) {
// fromIndex从第几个开始对比;匹配是,默认为0;
// sourceCount是data(大的字符串)的长度
if (fromIndex >= sourceCount) { // 这里data的长度如果是0,就直接被返回了
return (targetCount == 0 ? sourceCount : -1); // targetCount也是data的长度,所以直接返回了0,而不是返回-1
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
【如何修复】
底层逻辑了解清楚了,肯定不能改动了,我们就在封装的方法里修改。
两种解决:① 控制先判断为空就返回false ② 再加一个 data.indexOf(txt) != 0
这里选择第一种方法。最终选择,多加一个判断commons.lang3的StringUtils.isBlank(txt).
修改后的代码如下:
public static boolean isTxtInDate(String txt, String data) {
return StringUtils.isBlank(txt) == true ? false : data.indexOf(txt) != -1; // 如果txt为空,直接返回false(因为indexOf判断传入长度为0的字符串也会返回true)
}
StringUtils.isBlank()方法,需要引入的pom文件
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
【完整代码分享】
package com.nanfangzhe.anpai;
import org.apache.commons.lang3.StringUtils;
public class Demo {
public static void main(String[] args) {
Integer status = 0;
String textRule = "1,2,3";
System.out.println("状态必须符合:" + textRule);
System.out.println("status = 0:" + isTxtInDate(status.toString(), textRule) + "\n不继续往下执行");
System.out.println("status = \"\":" + isTxtInDate("", textRule) + "\n继续往下执行");
}
/**
* 判断data是否有txt
*
* @Method: isTxtInDate
* @author: nanfangzhe
* @date: 2022年4月11日
* @param txt
* @param data
* @return boolean
*/
public static boolean isTxtInDate(String txt, String data) {
return StringUtils.isBlank(txt) == true ? false : data.indexOf(txt) != -1; // 如果txt为空,直接返回false(因为indexOf判断传入长度为0的字符串也会返回true)
}
}
【总结】
封装方法时要考察该底层方法,进行也要测试到位!
文章小尾巴
文章写作、模板、文章小尾巴可参考:《写作“小心思”》
感谢你看到最后,最后再说两点~
①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
我是南方者,一个热爱计算机更热爱祖国的南方人。
(文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)