安全教育平台登录入口,中小学国家智慧教育平台
简介我最近用声纳扫描了代码,发现了一些问题。除了常见的错误和安全漏洞之外,方法使用中的一些错误引起了我的很大兴趣。为什么我对这些技术如此感兴趣?它们是如此令人困惑,以至于我们也可能会感到困惑。
1.replace是否会替换所有字符?在处理字符串时,经常希望将字符串中的字符A替换为字符B,例如ATYSDFA*Y。第一个想到的可能是使用替换方法。
如果你想用B替换所有A,你可以使用replaceAll方法。这非常直观,因为您只需查看该方法的名称就可以猜出该方法的用途。
那么问题来了,replace方法是否会替换掉所有匹配的字符呢?
JDK官方给出了答案。
此方法替换所有匹配的字符串。
Replace和replaceAll可以替换所有匹配的字符,但是它们有什么区别呢?
Replace 有两个重载方法。任一方法的参数:char oldChar 和char newChar 支持字符替换。
另一个方法source.replace('A', 'B') 的参数是CharSequence 替换,支持CharSequence 目标和字符串替换。
source.replace('A', 'B')replaceAll 方法的参数为字符串正则表达式和字符串替换,以及基于正则表达式的替换。常规字符串替换:
source.replaceAll('A', 'B') 正则表达式替换(将* 替换为C):
source.replaceAll('\\*', 'C') 顺便也可以使用replace方法将*替换为C。
source.replace('*', 'C') 不需要转义特殊字符。
不过,请注意不要这样写:
Source.replace('\\*', 'C') 阻止您替换字符串。
我还有一个小问题:如果我只想替换第一个匹配的字符串怎么办?
目前,您可以使用replaceFirst方法。
source.replaceFirst('A', 'B')2.不是可以用==让整数相等吗?不知道我在项目中见过没有,但是我的一些同事说=有人用=来比较两个整数类型的参数是否相等。
无论如何,我以前见过它,但是这个用法正确吗?
我的回答是,要看具体场景,不能说对错。
某些状态字段(例如orderStatus)的状态为-1(未订购)、0(已订购)、1(已付款)、2(已完成)、3(已取消)和5。
在本例中,使用==来确定相等性:
Integer orderStatus1=new Integer(1); Integer orderStatus2=new Integer(1); System.out.println(orderStatus1==orderStatus2); 返回的结果会是true吗?
答:这是不正确的。
有的同学可能会反对,但是不是有一个整数的缓存:-128到127吗?
为什么是谎言?
首先,我们来看看Integer 是如何构造的。
它实际上并不使用缓存。
那么缓存用在哪里呢?
答案就在valueOf 方法中。
如果我们把上面的判断改成这样,
String orderStatus1=new String('1');String orderStatus2=new String('1');System.out.println(Integer.valueOf(orderStatus1)==Integer.valueOf(orderStatus2));返回结果将为true你?
答:确实如此。
您应该养成良好的编码习惯,避免使用==来确定两个整数数据类型是否相等。它们仅在上述非常具体的情况下才相等。
相反,使用equals 方法来确定:
Integer orderStatus1=new Integer(1);Integer orderStatus2=new Integer(1);System.out.println(orderStatus1.equals(orderStatus2));3. 是否想在不损失精度的情况下使用BigDecimal?为了避免降级,请定义一些小数类型字段(例如金额)为BigDecimal 而不是Double。
使用Double 时可能会出现这种情况。
double amount1=0.02;double amount2=0.03;System.out.println(amount2 - amount1);在正常情况下,您会期望amount2 - amount1 等于0.01。
然而执行结果如下。
0.0099999999999999998 实际结果将小于预期结果。
两个Double类型的参数相减,转换为二进制数,但由于Double有16位有效数字,小数点后位数不够,出现错误。
常识表明使用BigDecimal 可以避免精度损失。
但是使用BigDecimal 时我们可以避免精度损失吗?
答案是否定的。
为什么?
BigDecimal amount1=new BigDecimal(0.02);BigDecimal amount2=new BigDecimal(0.03);System.out.println(amount2.subtract(amount1)); 在本例中,定义了两个BigDecimal 类型参数,构造函数使用以下命令初始化数据,然后打印两个参数相减的值。
结果:
0.009999999999999984734433411404097569175064563751220703125 不科学,但为什么仍然会失去精度?
jdk的BigDecimal构造方法有如下描述:
一般含义是该构造函数的结果可能是不可预测的。创建时可能是0.1,但实际值为0.1000000000000000055511151231257827021181583404541015625。
您会注意到,当您使用BigDecimal 构造函数初始化对象时,您也会丢失精度。
那么我们怎样才能避免失去准确性呢?
BigDecimal amount1=new BigDecimal(Double.toString(0.02));BigDecimal amount2=new BigDecimal(Double.toString(0.03));System.out.println(amount2.subtract(amount1));使用Double.toString 方法Double 类型十进制值的转换不会损失精度。
其实,还有更好的办法。
BigDecimal amount1=BigDecimal.valueOf(0.02);BigDecimal amount2=BigDecimal.valueOf(0.03);System.out.println(amount2.subtract(amount1)); 使用BigDecimal.valueOf 方法初始化BigDecimal 类型参数。没有精度损失。较新版本的阿里巴巴开发手册也推荐使用此方法创建BigDecimal参数。
4. 字符串不能用于字符串连接吗? String类型的字符串称为不可变序列,定义后对象的数据就不能改变。如果你想改变它,你需要创建一个新的对象。
String a='123';String b='456';String c=a + b;System.out.println(c);在连接多个字符串的场景中,对象被定义为String 类型,在这种情况下,许多无用的中间对象浪费内存空间并且效率较低。
目前,可以使用更高效的可变字符序列StringBuilder 和StringBuffer 来定义对象。
那么StringBuilder和StringBuffer有什么区别呢?
StringBuffer为每个main方法添加了synchronized关键字,而StringBuilder则没有。因此,StringBuffer是线程安全的,而StringBuilder则不是。
事实上,需要跨多线程连接字符串的场景很少,所以实际中很少使用StringBuffer。一般情况下,我们建议在连接字符串时使用StringBuilder。使用append方法添加字符串的效率更高,因为它只产生一个对象并且没有被锁定。
String a='123';String b='456';StringBuilder c=new StringBuilder();c.append(a).append(b);System.out.println(c); 现在重要的问题来了。连接字符串时使用String 类型对象是否比StringBuilder 类型对象效率低?
答案是否定的。
为什么?
使用javap -c StringTest 命令进行反编译。
可以看到,定义了两个String类型的参数,定义了一个StringBuilder类的参数,并使用了两次append方法来追加字符串。
如果您的代码如下所示:
String a='123';String b='789';String c=a + b;System.out.println(c);使用javap -c StringTest命令反编译会发生什么?
我惊讶地发现,还定义了两个String类型的参数,一个StringBuilder类的参数,并且使用了两次append方法来追加字符串。结果与上面相同。
**其实从jdk5开始,Java就对String类型字符串进行了优化,将其编译成字节码文件,然后优化成StringBuilder追加操作。
5. isEmpty 和isBlank 之间的区别在处理字符串时,您经常需要确定字符串是否为空。如果您不使用工具,则常见的决定如下:
if (null !=source !''.equals(source)) { System.out.println('notempty');} 不过每次都要做这个决定有点繁琐,这么多jar包串。天空被封装起来。目前市场上的一些主流工具包括:
Spring中的StringUtils jdbc中的StringUtils Apache common3中的StringUtils 但是,Spring的StringUtils类只有isEmpty方法,没有isNotEmpty方法。
jdbc的StringUtils类只有一个isNullOrEmpty方法,没有isNotNullOrEmpty方法。
因此,强烈推荐Apache common3的StringUtils类。它包括许多有用的空检测方法(例如isEmpty、isBlank、isNotEmpty、isNotBlank)和其他字符串处理方法。
问题是,isEmpty 和isBlank 有什么区别?
使用isEmpty 方法来确定:
StringUtils.isEmpty(null)=true StringUtils.isEmpty('')=true StringUtils.isEmpty(' ')=false StringUtils.isEmpty('bob')=false StringUtils.isEmpty('bob')=false 使用isBlank 方法并决定:
StringUtils.isBlank(null)=trueStringUtils.isBlank('')=trueStringUtils.isBlank(' ')=trueStringUtils.isBlank('bob')=falseStringUtils.isBlank('bob')=false 如下:如果这是一个空字符串,isNotEmpty 返回false,isBlank 返回true。
6.映射器查询结果是否应该被认为是空?我还记得当时我的同事在代码审查期间说:“你可以删除这里的空测试。”
List list=userMapper.query(search);if(CollectionUtils.isNotEmpty(list)) { List idList=list.stream().map(User:getId).collect(Collectors.toList());} 因为常识说,这通常所说的方法查询的集合可能为null,所以应该检查是否为null。然而,这是很不寻常的,在检查了mybatis源代码后,我发现确实可以删除空代码。
发生了什么?
mybatis的query方法最终会转发到DefaultResultSetHandler类的handleResultSets方法中。
此方法返回multipleResultsList 集合对象,但它永远不会为空,因为New 出现在方法的开头。
因此,如果您看到人们直接在项目代码中使用查询结果而不将其确定为null,请不要感到惊讶。
List list=userMapper.query(search);List idList=list.stream().map(User:getId).collect(Collectors.toList()); 底层对mapper进行了处理,所以不会出现空指针异常。
7. IndexOf方法的正确使用前段时间在review别人的代码时,遇到了如下indexOf的用法,印象非常深刻。
String source='#ATYSDFA*Y';if(source.indexOf('#') 0) { System.out.println('do Something');} 您认为这段代码打印会做些什么吗?
答案是否定的。
根据JDK官方的说法,如果不存在则返回-1。
IndexOf 方法返回字符串中指定元素的零位置。在上面的例子中,#位于字符串的第一个位置,因此调用indexOf方法后的值实际上是0。因此,如果条件为假,则do some 不会被打印。
如果要使用IndexOf 检查元素是否存在,请使用:
if(source.indexOf('#') -1) { System.out.println('do Something');}实际上有一个更复杂的contains 方法。
if(source.contains('#')) { System.out.println('do Something');} 作者:苏三硕技术链接:https://juejin.cn/post/6929029064955002888 来源:掘金
湖北电视台生活频道如何培养孩子的学习兴趣直播回放在哪看?直播视频回放地址入口[多图],湖北电视台生活频道
2025-08-20阴阳师4月22日更新内容:帝释天上线技能调整,红莲华冕活动来袭[多图],阴阳师4月22日更新的内容有哪些?版本更新
2025-08-20四川电视台经济频道如何培养孩子的学习习惯与方法直播在哪看?直播视频回放地址[多图],2021四川电视台经济频
2025-08-20