网易首页 > 网易号 > 正文 申请入驻

那些jdk中坑你没商量的方法

0
分享至

后台回复“大礼包”有惊喜礼包!

日英文

Tired heart is always hovering between adhering to and giving up, indecisive. Trouble is that memory is good, the mind should not mind will stay in memory.

心累,就是常常徘徊在坚持和放弃之间,举棋不定。烦恼,就是记性太好,该记的,不该记的都会留在记忆里。

每日掏心话

看着一路走来时的脚步,有苦,有甜,有笑,有泪。在走走停停之后,放慢了匆忙的脚步,感受那一路走来的弥足珍贵。

责编:乐乐 | 来自:cnblogs.com/wyq178/p/13520745.html

往日回顾:

正文

前言

jdk作为我们每天必备的调用类库,里面大量提供了基础类供我们使用.可以说离开jdk,我们的java代码寸步难行,jdk带给我们的便利可谓是不胜枚举,但同时这些方法在使用起来也存在一些坑,如果不注意就很容易掉入到陷阱里面,导致程序抛出错误。jdk中的很多方法都不会做非null判断,可能设计jdk的作者默认开发者已经处理好null值了.不过这个设计可能会造成很严重的后果,实在是暗藏杀机。比如今天早上我们查了一笔订单没有退款,查了一早上最终才发现是同事写的代码的BigDecimal的subtract方法的值没有做非null判断处理导致程序抛出了空指针异常,看似简单的异常却直接无法让很多订单退款,是在是小问题造成大事故。而要修补退款这个问题,要耗费很多时间去修补,出错的成本太高,本期我们就来看看jdk中那些坑你没商量的方法,这些方法很常见,相信你一定遇到过。

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

案发现场:某个鸟语花香的早上,我们在开心的敲着代码,突然客户群有人投诉反映,我们发给用户的短信有部分是尊敬的"null"你好,xx等。开发第一时间看了代码,觉的没有问题啊,为什么短信内容会出现用户名为null呢,不是经过了非空判断的吗?String.valueOf()是String提供的一个类型转换的方法,我们来看一下(代码简化过后的):

// 调用用户服务根据用户id获取用户信息
Map userInfo = userService.getUserInfoById(userId);
Object userNameObject = userInfo.get("name");
String userName = String.valueOf(userNameObject);
// 判空
if(userName!=null&&userName.length()>0) {
String message = getMessage(userName);
smsService.send(message);

这段代码是简化过的,主要作用就是通过用户服务根据id获取用户信息发送短信,后来经过定位发现了问题所在:首先用户的名字里有特殊的emoji符号,数据库写入的时候有部分写入失败,因为当时的

数据库字符格式并无法兼容emoji,而获取的时候因为这个问题值为null了,接下来是重点:

这里是重点,也是最大的坑人之处,注意这里返回了一个"null"的字符串,而不是null。这两个是有很大区别的,当进行非空判断的时候,返回的是ture。也就是这个"null"的字符串它是符合判空条件的!

正确的姿势是在String.valueOf方法前必须判空:

二:Integer.parseInt()方法很矫情

事故现场:一次业务场景为拉取订单,打出订单列表记录,财务人员需要拉出对账,结果总是发现很奇怪的一个现象,每次拉取少很多数据,。还好财务发现了,要不然和第三方财务对账就会亏很多钱...最终发现是订单的一个字段值转Integer出错了,那个订单下的字段值是120.0通过Integer.parseInt()直接报错了,恰好开发人员认为这段开发肯定没问题,因此就没有catch异常,最后找了很久才发现(因为涉及到第三方,还让别人查了半天...). 知道真相的我们都有点汗颜,这么丁点的错误排查了很久,实在是不应该啊。

Integer.parseInt()方法用于将字符串转化为Integer类型的方法,此方法的适用方向就显得比较窄,因为是String类型的参数,没有任何限定,当在传入一些比如50.0、20L、30d、40f这类数据的情况下,

我们来看一个栗子:

会抛出异常NumberFormatException:

事实上对于这样的数据,比如小数、浮点数据、long型数据它都可以自动转换,而不是给我们抛出烦人的报错信息,如果预先知道是整数或者小数,可以用Bigdecimal转换(注意此方法不适用于double和float、Long类型的数据,比如10d,20L)

对于浮点类型、long类型的数据可以用以下方法来处理:

推荐使用hutool的NumberUtil.parseInt()方法,充分考虑到了浮点、long、小数等类型数据可能带来的解析异常的问题,hutool是一个国人开源的工具类库,这里实名推荐,容错性和处理异常能力很强,可以自行百度搜索使用

三:Bigdecimal的除法坑你没商量

众所周知,BigDecimal是处理金额最有效的数据类型,一般进行财务报表计算的时候为了防止金额出现错误,一般情况下都会采用Bigdecimal,而double、float都会存在些许的误差。你开开心心的用Bigdecimal进行了计算,而最终的结果返回却有问题,我们来看一个栗子:

常见的除法用起来没有任何丝毫的问题,妥妥的没毛病.但是一旦程序中的数据出现以下情况,如果用Bigdecimal来接受前端的参数,而前端的参数是用户输入不确定的,一旦出现如下的数据,我们来看看结果:

执行结果一看,居然报错了哎:

这就是BidDecimal的坑,一旦返回的结果是无限循环小数,就会抛出ArithmeticException。因此在进行Bigdecimal除法的时候,需要进行保留小数的处理,正确的处理姿势:

我们先来看一个sample:

public List getUserNameList(String userId) {

List resultList = Collections.emptyList();
try {
resultList = userDao.getUserName(userId);
} catch (Exception ex) {
logger.info(ex);
}
return resultList;
}

这样会抛出错误,主要问题在于Collections.emptyList()并非我们平时看到的List,此list不支持add、remove方法,否则会抛出operationNotSupportException:

结果抛出异常:

原因是:Collections.emptyList返回的并不是我们平时认识的那个list,它是一个内部常量类:

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

这个list并不具有add、remove元素的能力,我猜想是因为jdk设计之初的想法是将这个list作为一种只读的list,并不提供数据的写入能力,因此它仅可作为一种 空值返回,无法进行删除、添加操作。

五:list可以一边删除一边遍历吗?

答案是肯定可以的,要不然的话list怎么删除数据呢,不过要注意遍历的姿势,我们再来看一个简单的例子:

很不幸,又双叒叕报错了:

仔细翻阅源码会发现,每次remove之前会检查元素的条数,如果发现预期的modCount和当前的modCount不一致就会抛出这个异常.modCount是list中用来记录修改次数的一个属性,当对元素进行统计的时候就会对该元素加1,而当对list边遍历边删除的话,就会造成

excepted与modCount不一致,从而抛出异常。

正确的删除姿势就是使用Iterator.remove进行遍历删除,可以规避这个问题。

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

六:总结

jdk的设计者有两个很大的特点:①大多不会做非null判断②**出现错误直接throw new Exception,容错性很差,**在实际开发中,面对jdk一定要谨慎使用,jdk提供了便利的同时,也有一些我们使用上的盲区,应该养成多看源码,多注意错误性处理,防止在小问题上栽大跟头。回到最开始说的那个subtract方法的问题,因为这个问题等需要我处理完之后用户才能收到退款,这直接造成了用户体验直线下降,而部分用户还直接打电话投诉。同事一个小小的不谨慎和马虎就给公司造成了很多负面影响,技术问题虽然不大但是带来的业务影响范围很严重。所以我们必须防微杜渐,小小的问题都得细细的打磨,才能避免很多问题的产生。

ps:接下来的部分会比较简易点,会阐述使用这个方法的问题或者存在的坑,这部分会持续更新,一旦在工作中发现有坑的方法我会及时更新**,同时欢迎大家留言补充这部分内容:**

七:持续更新 7.1 Bigdecimal在比较的时候,最好使用compareTo方法,不要使用equals方法,如下案例,虽然Bigdecimal重写了equals方法,但是使用会存在问题:

1和1.0在比较的时候返回了false,这是因为在equals的源码中进行了数据的scale(也就是精度)的比较,如果不一致就会返回false,如果使用compareTo方法就不存在这个问题

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

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

正确的姿势:

PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。


版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师,在后台回复“”即可。

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结。

别找了,想获取史上最简单的Java大厂面试题学习资料

扫下方二维码回复「面试」就好了

嘿,你在看吗

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
鲁尼悼念凯文-坎贝尔:凯文去世令我非常悲痛,他给予我很多帮助

鲁尼悼念凯文-坎贝尔:凯文去世令我非常悲痛,他给予我很多帮助

直播吧
2024-06-15 19:55:40
美联储对中国的第二波攻击已经发动,目标是掐死人民币国际化道路

美联储对中国的第二波攻击已经发动,目标是掐死人民币国际化道路

王思聪爱音乐
2024-06-15 22:37:27
3-0!6000万水货,打脸曼联名宿:西班牙走不远?一眼被看穿?

3-0!6000万水货,打脸曼联名宿:西班牙走不远?一眼被看穿?

贝塔说体育
2024-06-16 05:48:29
160国受邀,最终92国参加瑞士和平峰会,乌克兰外交获得小胜利

160国受邀,最终92国参加瑞士和平峰会,乌克兰外交获得小胜利

山河路口
2024-06-15 11:01:58
上海楼市全军覆没,上海房价跌破57000元,上海楼市6月分析

上海楼市全军覆没,上海房价跌破57000元,上海楼市6月分析

有事问彭叔
2024-06-15 12:13:13
普京:如果乌克兰放弃加入北约,俄罗斯将立即停火

普京:如果乌克兰放弃加入北约,俄罗斯将立即停火

花非花008
2024-06-14 21:54:14
凯特王妃与威廉王子首度公开亮相,暴瘦憔悴许多,三个孩子也出席

凯特王妃与威廉王子首度公开亮相,暴瘦憔悴许多,三个孩子也出席

笑猫说说
2024-06-15 17:47:08
无缘美加墨世界杯?巴西男足遇黑暗时刻,网友:66年的辉煌终结

无缘美加墨世界杯?巴西男足遇黑暗时刻,网友:66年的辉煌终结

体坛知识分子
2024-06-15 06:05:02
笑麻了!女子网购裤子裆部现“镂空”设计,商家回应:新潮流!

笑麻了!女子网购裤子裆部现“镂空”设计,商家回应:新潮流!

咖啡店的老板娘
2024-06-14 19:35:03
反转来了!周也光速认怂,和“六公主”碰拳和解,这公关绝了!

反转来了!周也光速认怂,和“六公主”碰拳和解,这公关绝了!

娱记掌门
2024-06-16 05:01:26
武统、和统都没希望了?台湾军事专家:中国大陆已经找到第三条路

武统、和统都没希望了?台湾军事专家:中国大陆已经找到第三条路

车马点兵V
2024-06-15 11:04:03
乌兹别克斯坦夫人给韩国夫人上了一堂出访课,这次遇到了强对手!

乌兹别克斯坦夫人给韩国夫人上了一堂出访课,这次遇到了强对手!

小毅讲历史
2024-06-15 19:11:33
汤普森做出决定!再见,勇士!你好,雷霆……

汤普森做出决定!再见,勇士!你好,雷霆……

篮球实战宝典
2024-06-15 16:06:16
银行副行长误将女员工表白视频群发,两人相差20岁,官方发声力挺

银行副行长误将女员工表白视频群发,两人相差20岁,官方发声力挺

求实者
2024-06-14 22:18:32
3-2大逆转!中国女排史诗一战,掀翻世界第1昂首出线,张常宁爆发

3-2大逆转!中国女排史诗一战,掀翻世界第1昂首出线,张常宁爆发

体坛纪录片
2024-06-15 22:41:36
当女人羞羞时,“咪咪”会发生什么变化?全看男人怎么操作

当女人羞羞时,“咪咪”会发生什么变化?全看男人怎么操作

水白头
2024-06-16 00:30:02
打断妻子多根肋骨,知名上市公司创始人被公诉!被指长期家暴,连咬带打,妻子怀孕7个月时仍被打得满头包,“为了孩子不得不忍”

打断妻子多根肋骨,知名上市公司创始人被公诉!被指长期家暴,连咬带打,妻子怀孕7个月时仍被打得满头包,“为了孩子不得不忍”

每日经济新闻
2024-06-15 18:22:06
随着许家印的没落,其女儿的生活也被曝光,奢侈程度令人咋舌

随着许家印的没落,其女儿的生活也被曝光,奢侈程度令人咋舌

天闻地知
2024-06-14 14:07:23
王思聪彻底栽了!黄一鸣孩子有“法定继承权”,万达迎来真公主?

王思聪彻底栽了!黄一鸣孩子有“法定继承权”,万达迎来真公主?

木子爱娱乐大号
2024-06-14 14:01:41
美媒:意总理召集G7开会,就像接待“避难客”

美媒:意总理召集G7开会,就像接待“避难客”

参考消息
2024-06-15 15:49:08
2024-06-16 11:52:49
程序员小乐
程序员小乐
有趣有内涵
3163文章数 9493关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

法国股市暴跌引发恐慌 马克龙:法国处于非常严峻时刻

头条要闻

法国股市暴跌引发恐慌 马克龙:法国处于非常严峻时刻

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

本地
教育
时尚
数码
公开课

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

教育要闻

四川卫视#四川卫视腹有诗书#“不积硅步,无以至千里,不积小流,无以成江海”,“成电”青年创新团队努力...

中年女性还是穿连衣裙最有气质!裙摆过膝、腰部收紧,巨显瘦

数码要闻

双 25G SFP28 网口,微星推出 D3052 服务器 AM5 MATX 主板

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版