Java 自定义异常(转载)
1.异常的分类
1. 非运行时异常(Checked Exception)
Java中凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常。
2. 运行时异常(Runtime Exception/Unchecked Exception)
- RuntimeException类直接继承自Exception类,称为运行时异常。
- Java中所有的运行时异常都直接或间接的继承自RuntimeException。
- Java中所有的异常类都直接或间接的继承自Exception。
2.异常的处理
一、对应非运行时异常,必须对其进行处理。处理方式有两种:
- 使用try…catch…finally语句块进行捕获
- 在产生异常的方法所在的方法声明throws Exception
二、对于运行时异常,可以不对其进行处理,也可以对其进行处理。一般情况下都不对其进行处理。
在使用Java API的方法时会产生异常,由于实际的需要,我们需要创建和使用自定义异常。使用全新的异常类,应用到系统程序中。
在介绍自定义异常时,首要先谈谈什么要使用自定义异常,使用自定义异常的好处。创建自定义异常是为了表示应用程序的一些错误类型,为代码可能发生的一个或多个问题提供新的含义;可以显示代码多个位置之间的错误的相似处,也可区分代码运行时可能出现的相似问题的一个或多个错误,或给出应用程序中一组错误的特殊含义。
应用场景
服务器的基本作用是处理与客户机的通信,若使用标准Java API(如java.io和java.net包中的类)来编写服务器,则可使编写的代码在多个位置抛出IOException。在设置服务器、等待客户机连接和获取通讯流时,可抛出IOException,在通信期间及试图断开连接时,也会抛出IOException。简而言之,服务器的各个部分都是引发IOException。
对于服务器而言,这样IOException意义不尽相同。虽然由同一异常类型表示,但与各个异常先关的业务含义存在差异,报告和恢复操作也不相同。所以,可以将一个异常集与服务器配置和启动问题关联,将另一个异常集与客户机通讯的实际行动关联,将第三个异常集与服务器关闭任务关联。使用自定义异常,可采用对应用程序有意义的方式来灵活地表示错误。
为此,我们需要使用自定义异常来定为问题,定位问题与异常实际准确的位置。
自定义异常类过程
1. 多数情况下,只需要继承异常类Exception, 经常需要定义一个或多个构造函数,以在对象中存储错误消息。
扩展:
- 类java.lang.Throwable是所有异常类的基类,它包括两个子类:Exception和Error,Exception类用于描述程序能够捕获的异常,如ClassNotFoundException。Error类用于指示合理的应用程序不应该试图捕获的严重问题,如虚拟机错误VirtualMachineError
- 自定义异常类可以继承Throwable类或者Exception类,而不要继承Error类。自定义异常类之间也可以有继承关系
- 需要为自定义异常类设计构造方法,以方便构造自定义异常对象。
在继承任何异常时,将自动继承Throwable类的一些标准特性,如:
- 错误消息
- 栈跟踪
- 异常包装
若要在异常中添加附加信息,则可以为类添加一些变量和方法。本例演示的自定义异常没有按照业务类型来命名,而是创建一个通用异常类,以retCd来区别发生异常的业务类型与发生位置,当然对于具体的retCd值,事先必须有具体的规定或说明。
package com.example.exception;import lombok.Getter;/*** 多数情况下,创建自定义异常需要继承Exception,本例继承Exception的子类RuntimeException* @author: GuanBin* @date: Created in 上午11:39 2019/5/22*/ @Getter public class CustomerException extends RuntimeException {private String resultCode; //异常对应的返回码private String messageDescription; //异常对应的描述信息public CustomerException (){super();}public CustomerException (String massage){super(massage);messageDescription=massage; } public CustomerException (String massage,String resultCode){ super(); this.resultCode=resultCode; this.messageDescription=massage; } }
2. 声明方法抛出自定义异常。为了使用自定义异常,必须通知调用代码的类:要准备处理这个异常类型。为此,声明一个或多个方法抛出异常。找到异常发生点,新建异常并加上关键字throw。
package com.example.java8test.exception;import com.example.exception.CustomerException;/*** @author: GuanBin* @date: Created in 上午11:46 2019/5/22*/ public class exceptionTest {public static void main(String[] args) {try {testException();} catch (CustomerException e) {e.printStackTrace();System.out.println("MsgDes\t" + e.getMessageDescription()); System.out.println("RetCd\t" + e.getResultCode()); } } public static void testException() throws CustomerException{ throw new CustomerException("10","String[] strs's length < 4"); } }
以下的自定义异常的最佳实践,摘自网络,经过参考扩展使用。
使用异常的最佳实践
下面的部分我们列出了客户端代码处理 API 抛出异常的一些最佳实现方法。
1. 记得释放资源
如果你正在用数据库或网络连接的资源,要记得释放它们。如果你使用的 API 仅仅使用 unchecked exception,你应该用完后释放它们,使用 try-final。
1 public void dataAccessCode() {2 Connection conn = null;3 try {4 conn = getConnection();5 //..some code that throws SQLException6 } catch (SQLException ex) {7 ex.printStacktrace(); 8 } finally { 9 DBUtil.closeConnection(conn); 10 } 11 } 12 13 class DBUtil { 14 public static void closeConnection 15 (Connection conn) { 16 try { 17 conn.close(); 18 } catch (SQLException ex) { 19 logger.error("Cannot close connection"); 20 throw new RuntimeException(ex); 21 } 22 } 23 }
DBUtil 是一个关闭连接的工具类。最重要的部分在于 finally,无论异常发不发生都会执行。在这个例子中,finally 关闭了连接,如果关闭过程中有问题发生的话,会抛出一个 RuntimeException。
2. 不要使用异常作控制流程之用
生成栈回溯是非常昂贵的,栈回溯的价值是在于调试。在流程控制中,栈回溯是应该避免的,因为客户端仅仅想知道如何继续。
下面的代码,一个自定义的异常 MaximumCountReachedException,用来控制流程。
1 public void useExceptionsForFlowControl() {2 try {3 while (true) {4 increaseCount();5 }6 } catch (MaximumCountReachedException ex) { 7 } 8 //Continue execution } 9 public void increaseCount ()throws MaximumCountReachedException { 10 if (count >= 5000) 11 throw new MaximumCountReachedException(); 12 }
useExceptionsForFlowControl()使用了一个无限的循环来递增计数器,直至异常被抛出。这样写不仅降低了代码的可读性,也让代码变得很慢。记住异常仅用在有异常发生的情况。
3. 不要忽略异常
当一个 API 方法抛出 checked exception 时,它是要试图告诉你你需要采取某些行动处理它。如果它对你来说没什么意义,不要犹豫,直接转换成 unchecked exception 抛出,千万不要仅仅用空的{}catch 它,然后当没事发生一样忽略它。
4. 不要 catch 最高层次的 exception
Unchecked exception 是继承自 RuntimeException 类的,而 RuntimeException 继承自 Exception。如果 catch Exception 的话,你也会 catch RuntimeException。
try{
..
}catch(Exception ex){
}
上面的代码会忽略掉 unchecked exception。
5. 仅记录 exception 一次
对同一个错误的栈回溯(stack trace)记录多次的话,会让程序员搞不清楚错误的原始来源。所以仅仅记录一次就够了。
总结:这里是我总结出的一些异常处理最佳实施方法。我并不想引起关于 checked exception 和 unchecked exception 的激烈争论。你可以根据你的需要来设计代码。我相信,随着时间的推移,我们会找到些更好的异常处理的方法的。
转载自:https://blog.csdn.net/mahoking/article/details/45064259
转载于:https://www.cnblogs.com/guanbin-529/p/10905445.html
Java 自定义异常(转载)相关推荐
- java+自定义异常类+输入若干成绩 为负数时输出抛出异常_java+自定义异常类+输入若干成绩 为...
java+自定义异常类+输入若干成绩 为 [2021-02-10 19:00:54] 简介: java中定义类的关键字是:"class".在Java中定义一个类,需要使用&quo ...
- 用枚举来处理java自定义异常
用枚举来处理java自定义异常 参考文章: (1)用枚举来处理java自定义异常 (2)https://www.cnblogs.com/leskang/p/8119099.html 备忘一下.
- java自定义异常及异常的抛出
java自定义异常及异常的抛出 参考文章: (1)java自定义异常及异常的抛出 (2)https://www.cnblogs.com/gemiaomiao/p/11900564.html 备忘一下.
- java catch自定义异常_java异常类-java自定义异常-嗨客网
Java异常类教程 我们在 我们可以看到,在 Exception 表示的是程序中出现了问题,可以直接使用 try - catch 来捕获处理.Error 一般值 Java常见异常 类名 描述 IOEx ...
- Java自定义异常、全局捕获异常、拦截器 实现动态控制登录超时
Java自定义异常.全局捕获异常.拦截器 实现动态控制登录超时 参考文章: (1)Java自定义异常.全局捕获异常.拦截器 实现动态控制登录超时 (2)https://www.cnblogs.com/ ...
- 【知了堂学习笔记】java 自定义异常
[知了堂学习笔记]java 自定义异常 参考文章: (1)[知了堂学习笔记]java 自定义异常 (2)https://www.cnblogs.com/pipixiao/p/7419902.html ...
- java 自定义异常实例分析_Java自定义异常类的实例详解
Java自定义异常类的实例详解 为什么要自己编写异常类?假如jdk里面没有提供的异常,我们就要自己写.我们常用的类ArithmeticException,NullPointerException,Ne ...
- Java自定义异常类以及异常拦截器
Java自定义异常类以及异常拦截器 参考文章: (1)Java自定义异常类以及异常拦截器 (2)https://www.cnblogs.com/acm-bingzi/p/java_exception. ...
- Java自定义异常封装
Java自定义异常封装 前言:异常的分类 1.为什么要自定义异常封装? 2.自定义异常封装有哪些优点? 2.1 提高系统的友好性 2.2 提高系统的可维护性 2.3 解决Java异常机制自身的缺陷 3 ...
- java 自定义异常 好处,什么是自定义异常 自定义异常类有什么好处呢
自定义异常类有什么好处呢? .比如下面这个程序. using System; class ex : ApplicationExcept小编已经无语了,怪不得没人回答... 基本上是鸡同鸭讲,建议你去C ...
最新文章
- MySQL 唯一索引 UNIQUE KEY 会导致死锁?
- oracle下使用sql命令,ORACLE笔记(2)ORACLE 学习中用到的SQL命令
- C#的TreeView标记
- mysql 语句优化实例_MySQL 语句优化实例
- SAP UI5 control id generation by jQuery
- Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
- C语言 传值和传指针的区别
- python-多线程共享内存
- 让LinqToSQL使用Web.Config中的链接字符串(修改Settings.Designer.cs)
- springcloud生产环境一般怎么部署_生产环境遇到这些ogg报错该怎么处理?
- python中dir函数的作用_【Python】Python内置函数dir详解
- Linux内核加载f2fs,安装f2fs工具以使用f2fs文件系统作为引导deepin系统分区
- NB-IoT未来发展,主要是靠什么驱动的?
- Germany Gone with honour - 德国队 带着胜利离开
- Windows XP默认用户自动登录
- 网约叫车出行小程序开发制作功能介绍
- 每日一篇系列---CSS3实现下雨动效
- 做BI的痛,你懂吗?
- TortoiseSVN (Subversion客户端) 使用手册(中文) (五)
- Appium Android Bootstrap源码分析之简介
热门文章
- Python3 基础学习笔记 C09【文件和异常】
- 【LeetCode-SQL每日一练】—— 627. 变更性别
- android手机设置时间设置,如何设置电信定制手机日期与时间
- php跨域session共享,PHP中利用COOKIE与SESSION联合实现SESSION跨域
- java中的并发类_java中并发常用工具类
- 【51nod - 1050】循环数组最大子段和(dp)
- *【HDU - 1042 】 N! (大数乘法)
- Thymeleaf模板引擎处理日期输入框回显问题type=“date“类型的坑 和 单选按钮、复选框的回显
- vb外部调用autocad_AutoCAD教程之图块的各种相关操作和概念
- 计算机的应用技术课程的看法,统计教学与计算机应用的几点看法论文