游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

处理异常的标准姿势,你学废了吗?

  前言
  在Java中应该如何处理异常,这个话题看似简单,不就是try。。。catch嘛,但是往往BUG更容易出现在一些简单的、容易忽略的地方。大多数成熟的开发团队对于如何进行异常处理都有一套规范和最佳实践。
  本期内容我整理了一些在我的团队正在使用的9个最佳实践,希望能让你对异常处理有所帮助。1、使用finally或try。。。with。。。resource关闭资源
  如果我们在try代码块中需要使用到一些资源,比如InputStream,在使用完之后我们需要将资源关闭。
  这是一个错误示例publicvoidtryResource(){FileInputStreaminputStreamnull;try{FilefilenewFile(。小黑说Java。txt);inputStreamnewFileInputStream(file);使用inputStream读取文件不要这样做inputStream。close();}catch(FileNotFoundExceptione){log。error(文件未找到,e);}catch(IOExceptione){log。error(文件读取异常,e);}}
  在上面这段代码中,只要在文件读取时没有出现异常,这段代码是可以正常工作的,但是只要在try块中的close()方法中抛出异常,资源就不会被关闭。
  所以这种情况我们应该将资源关闭的代码放在finally中或者使用try。。。with。。。resource语句。使用finally
  在finally块中的代码不管是否出现异常,都会被执行,因此可以确保资源对象被关闭。publicvoidcloseResourceInFinally(){FileInputStreaminputStreamnull;try{FilefilenewFile(。小黑说Java。txt);inputStreamnewFileInputStream(file);使用inputStream读取文件}catch(FileNotFoundExceptione){log。error(文件未找到,e);}finally{if(inputStream!null){try{inputStream。close();}catch(IOExceptione){log。error(资源关闭异常,e);}}}}使用try。。。with。。。resource
  如果你使用的JDK版本是1。7,那么也可以选择使用try。。。with。。。resource语句。如果你使用的资源类实现AutoCloseable接口,则可以使用这种方式。
  Java中的大多数标准资源类API都实现了这个接口。在try子句中打开资源,将会在try代码块执行完毕或异常处理后自动关闭资源对象。publicvoiduseTryWithResource(){FilefilenewFile(。小黑说Java。txt);try(FileInputStreaminputStreamnewFileInputStream(file);){使用inputStream读取文件}catch(FileNotFoundExceptione){log。error(文件未找到,e);}catch(IOExceptione){log。error(文件读取异常,e);}}2、使用更明确的异常
  如果我们的方法需要向外抛出异常,那么异常类型越具体越好。因为在外部调用你代码的其他人对你内部的实现逻辑可能并不清楚,所以要确保能提供给他尽可能多的信息,可以让别人在使用你的方法时更容易理解,这样调用方可以更好地处理抛出的异常。
  比如,在你的方法内容抛出NumberFormatException比抛出IllegalArgumentException或者直接抛出Exception,所代表的含义就会更明确。3、方法注释中对异常进行说明
  如果你的方法声明了可能会抛出异常,那么在方法的文档注释中,应该对异常进行说明。这和上一条的目的一样,都是为了让方法的调用者能提前获得更多的信息,方便他避免在调用你方法时出现异常,或者更明确如果进行异常处理。
  所以,我们应该在方法的文档注释中添加throws声明,并说明什么情况下会抛出对应的异常。这个方法内部做了什么什么事情。。。paraminputthrowsBusinessException如果出现xxx情况,则会抛出这个异常publicvoiddoSomething(Stringinput)throwsBusinessException{。。。}4、在异常中携带足够的描述信息
  这一点和前两条做法的目的类似。在异常中携带足够的描述信息,是为了在出现该异常时,能够在日志文件中查看异常信息时,能看到更有用的信息。
  所以我们应该尽可能准确地描述出为什么抛出了这个异常,并提供最相关的数据信息让别人定位。
  当然这里也不能太极端,你洋洋洒洒写一篇小作文,应该使用简短的一段信息描述,让运维同事能了解到这个问题的严重性,更轻松地分析问题所在。
  也不用提供一堆额外的冗余信息,尽量做到足够精准。比如当你再创建一个Long对象时如果传入一个字符串,就会抛出NumberFormatException。publicstaticvoidtestLong(){try{LongabcnewLong(ABC);}catch(NumberFormatExceptione){log。error(格式异常,e);}}
  NumberFormatException的类名已经告诉我们出现的是数字格式化异常,所以在message中只需要提供输入的字符串。如果你定义的异常类名不能很明确的表达出是什么异常,比如BusinessException,你就应该在message中表达出更多的信息。
  5、先捕获更明确的异常
  一般在我们使用的IDE中,如果当你在做异常捕获时,先捕获了不太具体的异常比如Exception,然后再捕获更具体的异常如IOException,都会提示我们后面的catch块无法到达。所以我们应该先捕获最具体的异常类,将不太具体的异常类的捕获放在最后。publicvoidcatchExceptions(){try{doSomething(小黑说Java);}catch(NumberFormatExceptione){log。error(格式异常,e);}catch(IllegalArgumentExceptione){log。error(非法参数,e);}}6、不要捕获Throwable
  Throwable是所有Exception和Error的父类。
  虽然可以在catch块中捕获它,但是我们不应该这样去做。因为如果使用了Throwable,那么不仅会对所有抛出的Exception进行捕获,还会捕获所有的Error。
  而当我们的程序抛出Error时表示是一个无法处理的严重问题,例如典型的OutofMemoryError,StackOverflowError等,这两个Error都是由程序无法控制并且不能处理的情况引起的。所以说,最好不要在你的catch中捕获Throwable,除非你非常确定try块中的代码抛出的是可以处理的异常情况。publicvoidcatchThrowable(){try{一些业务代码}catch(Throwablet){不要这样做}}7、不要将异常忽略
  在你开发的时候可能非常确定不会抛出异常,并且在你开发时确实没有发生过抛出异常的情况,所以你在catch块中没有对异常做任何处理。publicvoiddoNotIgnoreExceptions(){try{一些业务代码}catch(NumberFormatExceptione){认为永远不会执行到这里}}
  但是,你其实不确定在将来会不会有人在你的try块中添加新的代码,并且他可能也不会意识到他添加的代码会导致有异常抛出,这将会导致在线上真的有异常产生,但是没有一个人知道。
  所以,你至少应该在catch中打印一行日志,告诉运维同事,警报,这里出现了一个不可能会出现的异常。publicvoiddoNotIgnoreExceptions(){try{一些业务代码}catch(NumberFormatExceptione){log。error(警报,这里出现了一个不可能会出现的异常,e);}}8、不要打印日志后又将异常抛出
  这一条可能绝大多数人都会犯过,我见过非常多别人的代码在异常处理时,先打印了一行异常日志,然后将异常抛出,或者转成一个RuntimeException抛出。
  甚至在一些开源框架中都有出现过。publicvoidtestCatchEx(){try{newLong(heihei);}catch(NumberFormatExceptione){log。error(数字格式异常,e);throwe;}}
  你可能会认为这样做很直观,也没什么错,让调用你方法的人去处理就好了。但是这样一来,在日志中会对抛出的一个异常打印多条错误信息。
  重复的日志并没有带来任何有价值的信息,参考上面第4条中描述,在异常信息中应该携带足够的信息,并且要做到精准。如果需要在添加其他信息,你应该将捕获到的异常封装在你的自定义异常中再进行抛出。publicvoidwrapException(Stringinput)throwsBusinessException{try{dosomething}catch(NumberFormatExceptione){thrownewBusinessException(一段对异常的描述信息。,e);}}
  所以,我们应该只有在想对异常进行处理时捕获,否则就应该在抛出去,并且在方法前面上加以说明,让调用方去处理。9、在包装异常时使用原始异常
  通常在项目开发时,都会有一套自定义的异常,用于将API中的标准异常封装到自定义异常中,可以用于在外层做一些统一的异常处理。
  但是我们在使用自定义异常对原始异常进行封装时,需要确保将原始异常作为cause保存在自定义异常中,否则你在外层将会丢失原始异常的堆栈跟踪信息,到你你无法通过异常信息分析抛出异常的具体原因。publicvoidwrapException(Stringinput)throwsBusinessException{try{dosomething}catch(NumberFormatExceptione){将e作为构造参数中的causethrownewMyBusinessException(一段对异常的描述信息。,e);}}总结
  在抛出或者捕获异常时,我们应该考虑很多不同的事情,上面所说的大多数都是为了提高代码的可读性和提供给别人的API更易用。
  异常不仅是一种错误处理机制,同时还具备一定的信息传递作用。我们应该遵循这些异常处理的规则和最佳实践,写出更规范、不被别人吐槽的好代码。

触目惊心!这些贪腐和违规的上市公司高管们作者:墨鸣,编辑:小市妹近日,腾讯召开了一次出圈的内部会议。会上马化腾谈及腾讯内部的贪腐问题,直言触目惊心,马化腾称很多业务做不起来,就是因为贪腐漏洞太大,掏空了业务。……丁盛只有开国少将军衔,战功却是上将级别这4点经历罕有人及共和国的第一次大授衔是一项缜密繁琐的工作。军衔制的施行标志着我们人民军队逐渐正规化的开端。第一次大授衔之前,仅仅是从提议到筹备工作就长达数年之久,直到1955年初,中央军委才发……板门店谈判陷入僵局,李克农给了解方一张小纸条,起了关键作用1951年10月25日,板门店谈判开始,代表们落座后,朝鲜人民军代表首先发言。为了监督谈判会场中立化协定的实施,他建议设立一个参谋军官一级的监督小组。联合国军代表乔埃没加思考,……父亲消失22年后,小兵指着报纸上的中央司令喊爸爸,连长别乱说1949年10月份,广东人民终于等到了解放军的到来,当时的广东被十五万的国民党军队驻扎,解放军的邓华司令带兵前往围剿,国民党即便人数众多,但却一直不得民心,再加上全国各地都陆续……冲击NBA还是镀金?中国篮坛4人赴美,2人提前回国,张镇麟最这个夏天,关于多名年轻球员冲击NBA的计划,吸引不少球迷和媒体的关注,特别是张镇麟,曾凡博,郭昊文,余嘉豪4人,代表中国篮坛最强的天赋之一,如果说周琦之外,谁更加具有机会拿到N……3队开抢!大莫里斯新去向!或赴76人联手哈登,加盟公牛助德罗在新赛季开始前,关于自由球员马基夫莫里斯接下来的去向一事,可以说已经吸引了不少球迷和媒体的关注!上个赛季效力于热火队,大莫里斯虽然饱受伤病困扰,整个常规赛仅打了17场比赛……手机打开虚拟内存,有必要吗?虚拟内存技术,2021年正式登录安卓手机。虚拟内存融合技术,可以借一部分储存空间来充当虚拟内存,但是闪存的读写速度终究比不上内存。目前的手机厂商都喜欢将虚拟内存算成……社区团购大戏下半场,冷暖谁人知?社区团购大戏进入了下半程,阿里、京东、拼多多、美团等互联网巨头之间的战火日渐平息。一片嘘声中,有些曾经叱咤风云的主角领了盒饭,其他大大小小的角色也走到了命运三岔口。(图Pexe……3换1交易方案,湖人拒绝押宝一箭双雕,绿军提升上限更加全能凯尔特人和湖人一直是联盟传统的强队,如今他们都手握17个总冠军,谁能率先突围创造历史成为球迷津津乐道的话题。上赛季,由于塔图姆、布朗、斯玛特以及一众角色球员的出色发挥,凯尔特人……古代中国为什么要控制沙漠遍布的新疆,而不征服富饶的东南亚?古代中国,能对中国产生威胁的是北方地域的政权。不控制新疆,有很大的风险。解除北方危险后,必然会开拓东南亚。这是古中国的生存发展繁荣之路,今日中国依然如此。纵览古中国的威胁……资治通鉴(唐纪卷十八段译)司马光(北宋)……资治通鉴(唐纪卷十七段译)司马光(北宋)……
奥运冠军张常宁家庭太优秀!外公曾为国出征,父亲和丈夫皆是名将张常宁作为中国女排的主力成员,是一名非常优秀的女排球员,帮助中国女排夺取了很多的荣誉。而翻开它的家族来看,真是一个太优秀的大家庭,让人心生敬意。张常宁的外公曾作为军人为国出征,……53岁哈文越活越年轻!穿一身黑装丝毫不显老,反而霸气又时髦哈文曾是央视著名的导演,连续导演了多年春节联欢晚会,她知性优雅,才华出众。与其过世丈夫李咏的幸福恩爱的婚姻一直被外界称赞。现在丈夫虽已过世多年,但仍然青春活力满满。本期我们就来……建议中年女人想要老公每天追着夸皮肤好,一定要试试以油养肤最近跟朋友出去发现她的皮肤越来越好,同样到中年,人家明显感觉年轻了许多,脸上滋滋润润的。后来问她怎么皮肤这么好,原来她最近一直在用精油护肤。之前都听说过以油养肤皮肤越来越好,但……华为鸿蒙系统装机量超3亿台多家上市公司介入操作系统产业链本报记者贾丽经过一年的商业化探索,鸿蒙操作系统HarmonyOS发展路径及目标逐渐清晰。在工信部日前举行的主题为大力发展新一代信息技术产业会议上,工业和信息化部信息技术发……分享朋友圈的文案,干净利落,值得一读1、世界上有两个我,一个间歇性发奋图强,一个持续性堕落放纵。2、成年人稳定情绪的秘诀之一,就是把对他人的期待放到最低。3、这个世界上过得好的人,大部分是该吃吃,该喝……吴倩男人装封面穿吊带配黑丝露细腰美背性感撩人红裙妖娆妩媚头条创作挑战赛吴倩登《男人装》封面,一身黑色皮质抹胸搭配超短裤,这是一次新的惊喜,新的尝试。首页封面,吴倩以一袭黑色吊带抹胸亮相,长卷发自然垂落,仰着脸神情看上去十分享受……手游剑网1归来正式上线新资料片精武战魂3月23日消息,由西山居原班人马打造、西山居和盛趣游戏联合发行的武侠MMO手游《剑网1:归来》正式上线新资料片精武战魂,带来了新门派武魂堂、跨服新玩法等多项内容。值得一提……LSD赛道潜力巨大,如何布局?盘点不容错过的已发币热门标的!LSD赛道流动性质押赛道这两年增长迅速,俨然已经成为了DEFI里的常青藤,伴随着LDO的TVL不断地增长,此版块也爆发出了越来越大的潜力,未来成为千亿万亿板块都不再是空有的梦想……欧冠小组赛抽签出炉,我们看到了什么是欧足联套路和职业足球8月26日,202223赛季欧冠小组赛抽签出炉。分组详情如下:A组:阿贾克斯、利物浦、那不勒斯、格拉斯哥流浪者B组:波尔图、马德里竞技、勒沃库森、布鲁日……中国连续6个月抛售美债状态,美媒230吨黄金将从欧美运往中国近日,根据世界黄金协会的数据,中国市场对于黄金的需求极为强劲,7月中国黄金ETI包揽了亚洲地区的黄金净流入,数量达到了8。1吨。根据海关的相关数据,中国上半年共进口326吨黄金……CBA正负值排名最水外援林书豪第一,张镇麟第二,余嘉豪第四CBA已经进入到季后赛的第二轮,第一轮首钢队爆冷出局,山西队大战三场以下克上晋级;广东队、深圳队强势晋级。今天下午三点还将进行辽宁队对阵山西队的比赛。在季后赛的舞台上,各……最近这些年,为什么欧洲国家突然就不做手机了呢?我无比清楚地记得:很多年前在手机领域那可是欧洲国家一统江湖的状态,例如:大家耳熟能详的、80后都记忆犹新的诺基亚手机,这就是欧洲芬兰的产品;还有德国西门子手机等等。我自己……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网