Java日常开发的21个坑-JDK方法的坑-《Java笔记》

admin 2025-10-19 03:03:09 编程 来源:ZONE.CI 全球网 0 阅读模式

Java JDKJDK作为每天必备的调用类库,里面大量提供了基础类供开发者使用。可以说离开jdk,java代码寸步难行,jdk带来的便利可谓是不胜枚举,但同时这些方法在使用起来也存在一些坑,如果不注意就很容易掉入到陷阱里面,导致程序抛出错误。

一、String.valueOf()方法的陷阱

String.valueOf()是String提供的一个类型转换的方法,来看一下(代码简化过后的):

  1. // 调用用户服务根据用户id获取用户信息
  2. Map<String, Object> userInfo = userService.getUserInfoById(userId);
  3. Object userNameObject = userInfo.get("name");
  4. String userName = String.valueOf(userNameObject);
  5. // 判空
  6. if(userName!=null&&userName.length()>0) {
  7. String message = getMessage(userName);
  8. smsService.send(message);
  9. }

这段代码是简化过的,主要作用就是通过用户服务根据id获取用户信息发送短信,后来经过定位发现了问题所在:首先用户的名字里有特殊的emoji符号,数据库写入的时候有部分写入失败,因为当时的数据库字符格式并无法兼容emoji,而获取的时候因为这个问题值为null了,接下来是重点:这里是重点,也是最大的坑人之处,注意这里返回了一个”null”的字符串,而不是null。这两个是有很大区别的,当进行非空判断的时候,返回的是ture。也就是这个”null”的字符串它是符合判空条件的!正确的姿势是在String.valueOf方法前必须判空:

二、Integer.parseInt()方法的坑

Integer.parseInt()方法用于将字符串转化为Integer类型的方法,此方法的适用方向就显得比较窄,因为是String类型的参数,没有任何限定,当在传入一些比如50.0、20L、30d、40f这类数据的情况下,来看一个栗子:会抛出异常NumberFormatException:事实上对于这样的数据,比如小数、浮点数据、long型数据它都可以自动转换,而不是抛出烦人的报错信息,如果预先知道是整数或者小数,可以用Bigdecimal转换(注意此方法不适用于double和float、Long类型的数据,比如10d,20L)对于浮点类型、long类型的数据可以用以下方法来处理:推荐使用hutool的NumberUtil.parseInt()方法,充分考虑到了浮点、long、小数等类型数据可能带来的解析异常的问题。

三、Bigdecimal的除法

BigDecimal是处理金额最有效的数据类型,一般进行财务报表计算的时候为了防止金额出现错误,一般情况下都会采用Bigdecimal,而double、float都会存在些许的误差。用Bigdecimal进行了计算,而最终的结果返回却有问题,来看一个栗子:常见的除法用起来没有任何丝毫的问题,妥妥的没毛病,但是一旦程序中的数据出现以下情况,如果用Bigdecimal来接受前端的参数,而前端的参数是用户输入不确定的,一旦出现如下的数据,来看看结果:执行结果一看,居然报错了:这就是BigDecimal的坑,一旦返回的结果是无限循环小数,就会抛出ArithmeticException。因此在进行Bigdecimal除法的时候,需要进行保留小数的处理,正确的处理姿势:

四、Collections.emptyList()此list非彼list

先来看一个sample:

public%20List<String>%20getUserNameList(String%20userId)%20{%20%20%20%20List<String>%20resultList%20=%20Collections.emptyList();%20%20%20%20try%20{%20%20%20%20%20%20%20%20resultList%20=%20userDao.getUserName(userId);%20%20%20%20}%20catch%20(Exception%20ex)%20{%20%20%20%20%20%20%20%20logger.info(ex);%20%20%20%20}%20%20%20%20return%20resultList;}

这样会抛出错误,主要问题在于Collections.emptyList()并非平时看到的List,此list不支持add、remove方法,否则会抛出operationNotSupportException:结果抛出异常:原因是:Collections.emptyList返回的并不是平时认识的那个list,它是一个内部常量类:

public%20static%20final%20List%20EMPTY_LIST%20=%20new%20EmptyList<>();

这个list并不具有add、remove元素的能力。

五、list可以一边删除一边遍历吗

答案是肯定可以的,要不然的话list怎么删除数据呢,不过要注意遍历的姿势,再来看一个简单的例子:很不幸,又双叒叕报错了:仔细翻阅源码会发现,每次remove之前会检查元素的条数,如果发现预期的modCount和当前的modCount不一致就会抛出这个异常。modCount是list中用来记录修改次数的一个属性,当对元素进行统计的时候就会对该元素加1,而当对list边遍历边删除的话,就会造成excepted与modCount不一致,从而抛出异常。正确的删除姿势就是使用Iterator.remove进行遍历删除,可以规避这个问题。

List<Integer>%20list%20=%20new%20ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);Iterator<Integer>%20iterator%20=%20list.iterator();while%20(iterator.hasNext())%20{%20%20%20%20Integer%20integer%20=%20iterator.next();%20%20%20%20if%20(integer%20==%202)%20{%20%20%20%20%20%20%20%20iterator.remove();%20%20%20%20}}

六、总结

JDK的设计者有两个很大的特点:①大多不会做非null判断②出现错误直接throw%20new%20Exception,容错性很差。在实际开发中,面对jdk一定要谨慎使用,jdk提供了便利的同时,也有一些使用上的盲区,应该养成多看源码,多注意错误性处理,防止在小问题上栽大跟头。

七、补充

7.1%20Bigdecimal在比较的时候,最好使用compareTo方法,不要使用equals方法

如下案例,虽然Bigdecimal重写了equals方法,但是使用会存在问题:JDK方法的坑 - 图161和1.0在比较的时候返回了false,这是因为在equals的源码中进行了数据的scale(也就是精度)的比较,如果不一致就会返回false,如果使用compareTo方法就不存在这个问题

7.2 MySQL的减法计算如果有null值结果就为null

select 5-null 结果会返回null,所以在进行MySQL计算的时候,对于有可能出现null值的列一定要进行ifnull(field,0)的转换,将null值转化为0,否则就会出现一些意想不到的数据错误和空指针问题JDK方法的坑 - 图17正确的操作是:JDK方法的坑 - 图18

7.3 String的split方法在进行||分割的时候需要进行转义,否则结果会有问题

JDK方法的坑 - 图19JDK方法的坑 - 图20

以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  0