java try catch陷阱_Java异常处理最佳实践及陷阱防范

原标题:Java异常处理最佳实践及陷阱防范

33c7525e67eba7bff5a95e62f00f6042.png

出自《深夜里的程序猿》

作者:wangzenghuang

前言

不管在我们的工作还是生活中,总会出现各种“错误”,各种突发的“异常”。无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现。所以我们要时刻注意这些陷阱以及需要一套“最佳实践”来建立起一个完善的异常处理机制。

正文

异常分类

760dacce22d213f6fbfd265adddf5e76.png

首先,这里我画了一个异常分类的结构图。

在JDK中,Throwable是所有异常的父类,其下分为”Error“和”Exception“。Error意味着出现了不可控的严重错误,例如OutOfMemoryError。Exception则细分为两类,受检异常(check)需要我们手动try/catch或者在方法定义中throws,编译器在编译的时候会检查其合法性。非受检异常(uncheck)则不需要我们提前处理。这些简单的概念对于开发人员来说都是必须掌握的,这里就展示个图例,不做详细的描述了,我们的”正餐“还在后面。

重新认识try/catch/finally

说到异常处理,这里就不得不提try/catch/finally。try不可以单独存在,要么搭配catch,要么搭配finally,或者三者并存。

1、try代码块:监视代码块的执行,发现对应的的异常则跳转至catch,若无catch则直接到finally块。

2、catch代码块:发生对应的异常会执行里面的代码,要么处理,要么向上抛出。

3、finally代码块:不管是否有异常,都必执行,一般用来清理资源,释放连接等。然而有以下几种情况不会执行到这里的代码。

代码执行流程未进入try代码块。

代码在try代码块中发生死循环、死锁等状态。

在try代码块中执行了System.exit()操作。

try/catch/finally陷阱

下面介绍两个我们在使用tcf的时候可能会遇到的陷阱。

代码1

public class TCFDemo {

public static void main(String[] args) {

//11

System.out.println(returnVal());

}

static int returnVal(){

int a = 1;

int b = 10;

try{

return ++a;

}finally {

return ++b;

}

}

}

陷阱1:在finally中添加return语句,这样会覆盖掉try代码return的值,假如业务逻辑比较复杂,这里是很容易掉坑的,不利于排查错误。

代码2

public class TCFDemo {

public static void main(String[] args) {

Lock lock = new ReentrantLock();

try{

//有可能加锁失败

lock.lock();

//dost

}finally {

lock.unlock();

}

}

}

陷阱2:由于lock方法在加锁的时候有可能会抛出Uncheck异常,如果在try代码块中,必然会执行unlock方法,此时由于并没有加锁成功,所以会抛出IllegalMonitorStateException,这样一来后者的异常就覆盖掉了前者加锁失败的异常信息,所以我们应该把加锁的方法挪至try代码块外面。

最佳实践

好了,前面简单介绍了异常的分类以及try/catch/finally的注意事项,现在可以总结一下我们在异常处理的时候有哪些”最佳实践“了。

当需要向上抛出异常的时候,需根据当前业务场景定义具有业务含义的异常,优先使用行业内定义的异常或者团队内部定义好的。例如在使用dubbo进行远程服务调用超时的时候会抛出DubboTimeoutException,而不是直接把RuntimeException抛出。

请勿在finally代码块中使用return语句,避免返回值的判断变得复杂。

捕获异常具体的子类,而不是Exception,更不是throwable。这样会捕获所有的错误,包括JVM抛出的无法处理的严重错误。

切记更别忽视任何一个异常(catch住了不做任何处理),即使现在能确保不影响逻辑的正常运行,但是对于将来谁都无法保证代码会如何改动,别给自己挖坑。

不要使用异常当作控制流程来使用,这是一个很奇葩也很影响性能的做法。

清理资源,释放连接等操作一定要放在finally代码块中,防止内存泄漏,如果finally块处理的逻辑比较多且模块化,我们可以封装成工具方法调用,代码会比较简洁。

结尾

小小的异常,有大大的学问,你觉得呢?返回搜狐,查看更多

责任编辑:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vivo手机怎么投屏到电脑_投屏软件电脑加手机投屏软件投屏

优秀的资源工具可以让你事半功倍!本号文内资源已经手工转存整理,安全起见,回复 “领取资源” 按提示自助领取。今天分享的是一家公司出品的投屏神器。为避免被举报这里就不说出软件名了。它可以在局域网内把手机的屏幕投到电脑上,…

How to upload windows Sysprep Files to VMware vCenter Server Appliance 6.5(vC

vCSA5.5中可以登录到端口5480中去上传,vCSA 6.0以后就不支持了。但是可以通过Enable “Pi Shell”来做。 首先确保vCSA的ssh可用: 0. Make sure that SSH in enabled on the VCSA. Home > Administration > System configuration (under Deploymen…

开源短地址_如何在短短5分钟内完成您的第一个开源贡献

开源短地址by Roshan Jossey罗珊乔西(Roshan Jossey) 如何在短短5分钟内完成您的第一个开源贡献 (How to make your first open source contribution in just 5 minutes) The best way to level up your programming skills it to code more. The second best thing is to rea…

【Qt开发】QT对话框去掉帮助和关闭按钮 拦截QT关闭窗口的CloseEvent

建了一个对话框,我不想把边框去掉,只想去掉关闭按钮, setWindowFlags(windowFlags()&~Qt::WindowCloseButtonHint&~Qt::WindowContextHelpButtonHint); 结果那个问号的按钮去掉了,但是关闭按钮还在,求助啊 set…

Vivado Design Suite用户指南之约束的使用第二部分(约束方法论)

Constraints Methodology(约束方法论) 关于约束方法论 设计约束定义了编译流程必须满足的要求,以使设计在板上起作用。 并非所有步骤都使用所有约束在编译流程中。 例如,物理约束仅在实现步骤期间使用(即,由…

eval函数 php_PHP的一句话木马代码和函数eval的简介

大清早的刚从床上爬起来。雨落就跑来找我问我这段代码是什么意思<?php eval($_POST[pp]);?>看了一下&#xff0c;post接收pp的值&#xff0c;抑制错误输出。呵呵开个玩笑&#xff0c;其实不是这么简单&#xff0c;这是一段PHP木马代码&#xff0c;也就是我们所说的后门…

linux安装python_Python - 爱豆

Python下载Python最新源码&#xff0c;二进制文档&#xff0c;新闻资讯等可以在Python的官网查看到&#xff1a;Python官网&#xff1a;你可以在以下链接中下载 Python 的文档&#xff0c;你可以下载 HTML、PDF 和 PostScript 等格式的文档。Python文档下载地址&#xff1a;doc…

如何将您的#100DaysOfCode登录转换为视觉体验

by Joe Warren通过乔沃伦 如何将您的&#xff03;100DaysOfCode登录转换为视觉体验 (How to Transform Your #100DaysOfCode Log Into a Visual Experience) Learning how to code is an unrivaled modern experience. As an aspiring developer, no matter what level you’r…

Python中集合(set)的操作及一些比较常见的用法

Python除了List、Tuple、Dict等常用数据类型外&#xff0c;还有一种数据类型叫做集合&#xff08;set&#xff09;&#xff0c;集合的最大特点是&#xff1a;集合里边的元素是不可重复的并且集合内的元素还是无序的&#xff0c;所以一般情况下集合常用的两个场景是&#xff1a;…

php中的图像下载函数,PHP实现的下载远程图片自定义函数分享

/*** PHP下载远程图片到本地** param $url string 远程文件地址* param $filename string 保存后的文件名(为空时则为随机生成的文件名&#xff0c;否则为原文件名)* param $fileType array 允许的文件类型* param $dirName string 文件保存的路径(路径其余部分根据时间系统自动…

Linux 文件的压缩与解压

1. tar结尾压缩命令 [roottest ~]# tar -cvf grub.tar /boot/grub/ 查看压缩包文件 [roottest ~]# tar -vtf grub.tar 解压文件 #tar -xvf grub.tar # tar -xvf grub.tar -C 解压目录 2. gz结尾压缩命令 # tar -zcvf grub.tar.gz /boot/grub gz结尾解压命令 #tar -zxvf gr…

深度学习笔记-卷积神经网络CNN与循环神经网络RNN有什么区别?

转载 https://blog.csdn.net/weixin_35227692/article/details/79223536转载于:https://www.cnblogs.com/USTBlxq/p/10445268.html

参考框架 系统 基准_带有基准的前端框架的实际比较

参考框架 系统 基准by Jacek Schae由Jacek Schae 带有基准的前端框架的实际比较 (A Real-World Comparison of Front-End Frameworks with Benchmarks) UPDATE: There is a newer version of this article更新&#xff1a;本文有较新的版本 A Real-World Comparison of Front…

ppt复制切片器_零基础小白自学PPT快速入门到精通(上)

零基础小白如何自学PPT快速入门到精通呢&#xff1f;40个保姆级小技巧助力你高效掌握PPT基础操作&#xff01;PPT在学习与工作中的应用越来越广泛&#xff1a;在学校时免不了要做毕业答辩、毕业论文&#xff0c;工作中时常要进行复盘总结、工作汇报、推广方案&#xff0c;有时甚…

网络安全初创公司SafeBreach获1500万美元A轮融资

今天&#xff0c;网络安全初创公司 SafeBreach 宣布完成1500 万美元 A 轮融资&#xff0c;新投资者德国电信、惠普公司、 Maverick Ventures 及现有投资者 Sequoia Capital 和 Shlomo Kramer 参投。公司计划利用本轮融资加大研发力度&#xff0c;扩大销售及营销团队&#xff0c…

php网站分区,PHP - Manual: 分区和分片 (官方文档)

分区和分片数据库群组是由于各种各样的原因建立的&#xff0c;他可以提升处理能力、容忍错误&#xff0c;并且提升大量服务器同时工作的的性能。群组有时会组合分区和共享功能&#xff0c;来将大量复杂的任务分拆成更加简单的任务&#xff0c;更加可控的单元。插件可以支持各种…

webBroser获取cookie

//取当前webBrowser登录后的Cookie值 [DllImport("wininet.dll", CharSet CharSet.Auto, SetLastError true)]static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref int pcchCookieData, int dwFlags…

了解Linux操作系统发展阶段

一、硬件与软件发展历史 计算机由硬件和软件组成结构 二、Linux的发展史 Linux 操作系统是Unix操作系统的一种克隆系统。它诞生于1991年的10月5日&#xff08;只是第一次正式向外公布的时间&#xff09;。以后借助于Internet网络&#xff0c;并经过全世界各地计算机爱好者的共同…

c gui qt 4编程第二版_面试官问Linux下如何编译C程序,如何回答?为你编译演示

文章来源&#xff1a;嵌入式大杂烩 作者&#xff1a;ZhengNLWindows下常用IDE来编译&#xff0c;Linux下直接使用gcc来编译&#xff0c;编译过程是Linux嵌入式编程的基础&#xff0c;也是嵌入式高频基础面试问题。一、命令行编译及各个细分编译过程hello.c示例代码&#xff1a;…

Python基础-----列表、元组、集合(2)

raw_input ##字符类型input##数值类型##格式化输出注释切片s[2:5]##切片从2开始到5&#xff0c;不包括5[kioskfoundation39 mnt]$ pythonPython 2.7.5 (default, Oct 11 2015, 17:47:16) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2Type "help", "copyri…