Java异常处理原则与技巧总结

  一  处理原则

  Java异常代码中我们使用异常的目的是让异常的异常类型来提示“什么”被抛出了--- 即出了什么问题;用异常的栈打印信息来跟踪异常在“哪里”抛出 --- 即哪里出了问题;

  异常提示信息来提示“为什么”会抛出 --- 即出问题的原因。在对异常进行处理时,遵循以下原则可以有助于在调试过程中最大限度的使用好异常。

  1. 具体明确
  2. 提早抛出
  3. 延迟捕获

  1.具体明确

  具体明确指的是在抛出异常时需要针对具体问题来抛出异常,抛出的异常要足够具体详细;在捕获异常时需要对捕获的异常进行细分,这时会有多个catch语句块,这几个catch块中间泛化程度越低的异常需要越放在

  前面捕获,泛化程度高的异常捕获放在后面,这样的好处是如果出现异常可以近可能得明确异常的具体类型是什么。

  例如 FileInputStream 的一个构造方法如下, 对file对象做检查后判断file是否有效,如果无效直接抛出FileNotFoundException,而不是IOException或者其他更宽泛的Exception

    public FileInputStream(File file) throws FileNotFoundException {String name = (file != null ? file.getPath() : null);SecurityManager security = System.getSecurityManager();if (security != null) {security.checkRead(name);}if (name == null) {throw new NullPointerException();}if (file.isInvalid()) {throw new FileNotFoundException("Invalid file path");}fd = new FileDescriptor();fd.attach(this);path = name;open(name);}

  同样的,在对异常做捕获处理时,也需要做到具体明确,以下try语句块中read()和close方法均会抛出IOException而FileInputStream()抛出的是FileNotFoundException

  事实上FileNotFoundException继承自IOException,用一个IOException 就可以囊括所有的异常,这里仍然使用了两个catch块来分别捕获,为的就是方便定位异常问题。

    public void foo1(String fileName){File file = new File(fileName);InputStream in = null;try {in = new FileInputStream(file);Integer num = in.read();in.close();} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e){e.printStackTrace();}}

 

  2.提早抛出

  提早抛出的基本目的还是为了防止问题扩散,这样出现异常的话排查起来会比较耗时,比较典型的一种情况是 NPE(NullPointerException),当某个参数对象为null时,如果不提早判断并抛出异常的话,这个null可能

  会藏的比较深,等到出现NPE时就需要往回追溯代码了。这样就给排查问题增加了难度。所以我们的处理原则是出现问题就及早抛出异常。

  例如 上面FileInputStream 的构造方法,在使用前就对File 的path做了判断,如果为null 就及早的抛出NullPointerException,防止在后面open方法中传入一个null,从而简化了出现异常的情况,方便定位问题。

 

  3.延迟捕获

  延迟捕获说的是对异常的捕获和处理需要根据当前代码的能力来做,如果当前方法内无法对异常做处理,即使出现了检查异常也应该考虑将异常抛出给调用者做处理,如果调用者也无法处理理论上他也应该继续上抛,

  这样异常最终会在一个适当的位置被catch下来,而比起异常出现的位置,异常的捕获和处理是延迟了很多。但是也避免了不恰当的处理。

 

  二  处理技巧

  对于异常的处理,能避免的异常,尽量在事先做判断来避免异常的发生,当判断时发现逻辑上已经不能往下走了,需要停止流程,这时候将异常抛出并准确的提示使用者问题所在。

  对于事先无法预判的异常需要对其进行处理。

  异常分运行时异常 RuntimeException 和 检查异常Checked Exception,运行时异常一般用在由于接口方法使用不当的时候

  如: 使用了null获取属性方法, 数组下标越界,除法运算除以0等

  • 如果你调用服务方法的方式不正确,你应该马上修改代码,避免发生RuntimeException
  • 如果是用户方法调用你的方法的方式不正确,你应该立刻抛出RuntimeException,强制让使用者修正代码或改变使用方式,防止问题蔓延
  • 一般情况下,不要捕获或声明RuntimeException,需要做的是完善程序代码。因为问题在于你的程序本身有问题,如果你用异常流程处理了,反而让正常流程问题一直存在

 

  对于检查异常,一般先看能不能处理,能处理的异常使用try-catch 语句块捕获处理,不能处理使用throws 分类型抛出给上一级处理

  使用try-catch语句块处理时一般需要注意以下几方面

  1. try语句块内要分清稳定代码和非稳定代码,对于稳定的不会出现异常的代码不要放到try语句块中
  2. catch捕获的异常一定要处理
  3. 若使用了finally 语句块,在语句块内一定要对资源对象,流对象进行关闭(jdk1.7之后 可以使用try-with-resources替代)
  4. finally中不要使用return语句,因为finally语句块最后一定会执行,这里的return语句会覆盖之前的return语句

 

  参考:

  [1] 有效处理javay异常的三个原则

  [2] 阿里巴巴Java开发手册

 

转载于:https://www.cnblogs.com/mingorun/p/8900449.html

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

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

相关文章

python三阶魔方_三阶魔方自动求解及动态可视化matlab代码

三阶魔方自动求解及动态可视化matlab代码思路与步骤三阶魔方有6个面,每个面有333\times333小块,用一个6336\times3\times3633的矩阵来保存魔方的状态;定义412种魔方旋转行为:整体旋转(左右上下共4种方式AaCc),侧面(6个…

Qt 常用类——QStandardItemModel

转载:落叶知秋时 类QabstractItemModel,QabstractListModel,QAbstractTableModel不保存数据,用户需要从这些类派生出子类,并在子类中定义某种数据结构来保存数据。 与此不同,类QStandardItemModel负责保存数…

thinkphp mysql 中文_耗时5天解决thinkphp连接mysql中文乱码的问题

坑大,或者不大,它就在那里,等着你进。先前修改成熟的一个基于thinkphp3.1.2的后台框架,里面有我的autoCode,本来在新项目上不想再用这么落后的版本,但考虑到后台项目不对外使用,重点是autoCode是…

bzoj3203: [Sdoi2013]保护出题人

我三分这么好吗居然1A啦???提交的时候只是想着先WA一次的。。。。 这题真的很妙啊 首先第一步,就是把僵尸的生命值取一个前缀和,这样造成伤害的时候,可以视为同时对所有僵尸造成伤害。 那么就可以得到一个柿…

ad19原理图标注_AD19中原理图的模板如何进行编辑?

我们在进行原理图设计的时候,有时候不想去用软件自带默认的模板,想要用自己设计的模板,就涉及到我们的模板怎么去编辑的呢?我们应该如何去编辑原理图自己设计的模板?操作步骤是怎么的呢?我们今天就以AD19为…

mysql+秘密_mysql不被人知的秘密

http://blog.csdn.net/yueguanghaidao/article/details/69333872011先建立两张表。1.student表2.grade表一:mysql的复制技术1.表与数据的复制->>实现表结构和数据的同步create table desttable select * from srctable;(desttable:目标表,srctable…

项目管理中风险评价的必要性

摘要:在项目管理实践中,风险是时时存在的。 因此,如何评价、度量风险的大小,确定可接受风险和不可接受风险,对不可接受风险作进一步分析,制定补偿措施,将风险减至最小或可以接受的水平&#xff…

mysql一个表几亿数据_如何在mysql 造1亿条记录的大容量数据表?

背景及目标:现有数据1000w单表,为压力测试准备1亿条数据。步骤:1.将1000w条记录,除id外都导入到多个文件中://DELIMITERDROP PROCEDURE if EXISTS createManyTable;create PROCEDURE createManyTable()BEGINDECLARE i …

windows键盘在mac上怎么识别_Mac电脑怎么使用pc键盘?

苹果电脑一般需要使用配套的mac键盘,毕竟按键和普通pc键盘不一样。但是总会遇到一些情况,比如配套的mac键盘坏了,而刚好有一个pc键盘,那么这时候苹果电脑要怎么用pc键盘呢?这边小编跟大家介绍mac电脑连接pc键盘以及设置…

LOJ#6002. 「网络流 24 题」最小路径覆盖

模板。 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 //#include<time.h>5 //#include<complex>6 //#include<set>7 //#include<queue>8 #include<algorithm>9 #include<stdlib.h>10 using namespace s…

zabbix mysql设置中文乱码_解决zabbix监控因php问题导致图形界面中文乱码方法

解决因编译php中添加了-enable-gd-jis-conv选项导致Zabbix监控系统图形界面中文乱码问题现象&#xff1a;php编译参数&#xff1a;说明&#xff1a;如果PHP编译时启用–enable-gd-jis-conv选项的话&#xff0c;那么非ASCII字符(例如汉字、拼音、希腊文和箭头) 会被当成EUC-JP编…

熟悉常用的HDFS操作

一、Hadoop提供的Shell命令完成相同任务&#xff1a; 在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件txt&#xff0c;里面可以随意输入一些单词.在本地查看文件位置&#xff08;ls&#xff09;在本地显示文件内容使用命令把本地文件系统中的“txt”上传到HDFS中的当…

mysql 低端_mysql入门

相关了解(重点内容从标题一开始)目前主流数据库有:sqlserver, mysql, Qracle, SQLite, Access, MS SQL Server等, 我主要说的是mysql;以下几点需要记住!!!SQL包括了所有对数据库的操作, 主要由4个部分组1. 数据库定义语言(DDL): 用于定义和管理数据库对象, 包括数据库, 基本表,…

阿里云服务器由于被检测到对外攻击,已阻断该服务器对其它服务器端口的访问...

问题&#xff1a; (系统&#xff1a;CentOS 7.2 ) 前几天在阿里云服务器安装了Redis, 刚开始没有设置redis密码, 后台阿里云发送多次邮件提示如下&#xff1a; 经过几次波折才发现并彻底解决了问题&#xff1a; 原因&#xff1a; 估计是因为 Redis服务开启时没有设置密码 &…

opencv rect画旋转矩形_在opencv c中绘制旋转的矩形

既然你想要一个填充的矩形,你应该使用fillConvexPoly&#xff1a;// Include center point of your rectangle, size of your rectangle and the degrees of rotationvoid DrawRotatedRectangle(cv::Mat& image, cv::Point centerPoint, cv::Size rectangleSize, double ro…

批量找注入 python3+sqlmap结合

注入一直都是用sqlmap 导致本来就不怎么精通的手工注入现在就忘的一干二净 想实战练习 却一时又找不到有注入的网站 于是便有了这篇文章 想找个批量获取域名链接的工具 但都是只是获取域名而已 都没获取后面的参数 于是自己写了个只获取bing前10页的结果 输入q 结束循环…

python collections模块_Python 的collections模块

前言&#xff1a;collections是实现了特定目标的容器&#xff0c;以提供python标准内建容器dict,list,set和tuple的替代选择。CounterCounter是一个dict子类&#xff0c;主要是用来对你访问的对象的频率进行计数import collections#统计字符出现的次数test1 collections.Count…

C# VS2017 winForm 使tableLayoutPanel 不闪烁

//设置tablelayoutpanel控件的DoubleBuffered 属性为true&#xff0c;这样可以减少或消除由于不断重绘所显示图面的某些部分而导致的闪烁 private void Form_PrintPreview_Load(object sender, EventArgs e){//开启双缓冲&#xff0c;改善TableLayoutPanel闪烁问题TableLayoutP…

java 继承调用_【JAVA学习】继承中函数调用机制

类(类的对象)在调用函数时&#xff0c;究竟哪一个函数被调用&#xff0c;是存在特定的机制的&#xff0c;现在我们来梳理下其步骤。步骤一&#xff1a;当其调用一个函数的时候&#xff0c;编译器根据其声明的变量类型和调用的函数名字找到所有此“类”和其父类中具有同名的函数…

golang 反射

参考&#xff1a;|--http://blog.51cto.com/speakingbaicai/1707637 |--https://studygolang.com/articles/6324 反射是在golang程序运行时检查变量所具有类型的一种机制。由于反射可以得出关于变量结构的数据&#xff08;即“关于数据的数据”&#xff09;&#xff0c;所以这也…