Java自定义异常与异常使用的最佳方式

目录
  • 异常的分类
    • 1. 非运行时异常(Checked Exception)
    • 2. 运行时异常(Runtime Exception/Unchecked Exception)
  • 异常的处理
    • 一、对应非运行时异常,必须对其进行处理
    • 二、对于运行时异常,可以不对其进行处理
  • 应用场景
  • 自定义异常类过程
    • 1. 多数情况下
      • 扩展:
    • 2. 声明方法抛出自定义异常
    • 3.自定义异常测试操作
  • 使用异常的最佳实践
    • 1. 记得释放资源
    • 2. 不要使用异常作控制流程之用
    • 3. 不要忽略异常
    • 4. 不要 catch 最高层次的 exception
    • 5. 仅记录 exception 一次
  • 总结:

异常的分类

1. 非运行时异常(Checked Exception)

Java中凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常。

2. 运行时异常(Runtime Exception/Unchecked Exception)

RuntimeException类直接继承自Exception类,称为运行时异常。Java中所有的运行时异常都直接或间接的继承自RuntimeException。

Java中所有的异常类都直接或间接的继承自Exception。

异常的处理

一、对应非运行时异常,必须对其进行处理

处理方式有两种:

  • 使用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值,事先必须有具体的规定或说明。

/**
 * 多数情况下,创建自定义异常需要继承Exception,本例继承Exception的子类RuntimeException
 * @author Mahc
 *
 */
public class CustomerException extends RuntimeException {

	private String retCd ;  //异常对应的返回码
	private String msgDes;  //异常对应的描述信息
	public CustomerException() {
		super();
	}

	public CustomerException(String message) {
		super(message);
		msgDes = message;
	}

	public CustomerException(String retCd, String msgDes) {
		super();
		this.retCd = retCd;
		this.msgDes = msgDes;
	}

	public String getRetCd() {
		return retCd;
	}

	public String getMsgDes() {
		return msgDes;
	}
}

2. 声明方法抛出自定义异常

为了使用自定义异常,必须通知调用代码的类:要准备处理这个异常类型。为此,声明一个或多个方法抛出异常。找到异常发生点,新建异常并加上关键字throw。

public class TestClass {
 public void testException() throws CustomerException {
  try {
<p>   //..some code that throws <span style="font-family:SimSun;">CustomerException</span></p>  } catch (Exception e) {
   throw new CustomerException("14000001", "String[] strs's length < 4");
  }
 }
}

3.自定义异常测试操作

public class TestCustomerException {
 public static void main(String[] args) {
  try {
   TestClass testClass = new TestClass();
   testClass.testException();
  } catch (CustomerException e) {
   e.printStackTrace();
   System.out.println("MsgDes\t"+e.getMsgDes());
   System.out.println("RetCd\t"+e.getRetCd());
  }
 }
}

以下的自定义异常的最佳实践,摘自网络,经过参考扩展使用。

使用异常的最佳实践

下面的部分我们列出了客户端代码处理 API 抛出异常的一些最佳实现方法。

1. 记得释放资源

如果你正在用数据库或网络连接的资源,要记得释放它们。如果你使用的 API 仅仅使用 unchecked exception,你应该用完后释放它们,使用 try-final。

public void dataAccessCode (){
    Connection conn = null;
    try{
        conn = getConnection ();
        ..some code that throws SQLException
    }catch(SQLException ex){
        ex.printStacktrace ();
    } finally{
        DBUtil.closeConnection (conn);
    }
}
 class DBUtil{
    public static void closeConnection
        (Connection conn){
        try{
            conn.close ();
        } catch(SQLException ex){
            logger.error ("Cannot close connection");
            throw new RuntimeException (ex);
        }
    }
}

DBUtil 是一个关闭连接的工具类。最重要的部分在于 finally,无论异常发不发生都会执行。在这个例子中,finally 关闭了连接,如果关闭过程中有问题发生的话,会抛出一个 RuntimeException。

2. 不要使用异常作控制流程之用

生成栈回溯是非常昂贵的,栈回溯的价值是在于调试。在流程控制中,栈回溯是应该避免的,因为客户端仅仅想知道如何继续。

下面的代码,一个自定义的异常 MaximumCountReachedException,用来控制流程。

public void useExceptionsForFlowControl () {
    try {
        while (true) {
            increaseCount ();
        }
    } catch (MaximumCountReachedException ex) {
    }
    //Continue execution }
 public void increaseCount ()
    throws MaximumCountReachedException {
    if (count >= 5000)
        throw new MaximumCountReachedException ();
}

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 的激烈争论。你可以根据你的需要来设计代码。我相信,随着时间的推移,我们会找到些更好的异常处理的方法的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们.

(0)

相关推荐

  • java自定义异常打印内容详解

    本文实例为大家分享了java自定义异常打印内容的具体代码,供大家参考,具体内容如下 背景:在开发中,我们可能会使用到自定义异常,但是,这个自定义异常在打印日志时,往往打印的内容比较多. 1.自定义异常打印内容 可以看到,虽然我们使用的是自定义异常,但是当抛出时,还是会打印出堆栈的全部信息. 2.查看源码 通过查看源码,我们可以得知,当抛出异常时,程序会调用此异常的fillInStackTrace方法,但是,大部分异常都没有对该方法做处理.基本是调用super的方法. 可以看到,此方法的父类实现,

  • Java抛出异常与自定义异常类应用示例

    本文实例讲述了Java抛出异常与自定义异常类.分享给大家供大家参考,具体如下: 异常处理常用方法: 常用的异常处理方法有: 一.try()catch() 语句 二.throw / throws 语句 三.自定义异常类 用途: 众所周知,当程序运行过程中,如果遇到了错误(比如数组下标越界,空指针等)程序就会自动终止,但这种错误一般是偶然的,可能是用户输入不呵呵程序编写者的意图导致,而不是程序本身问题,这是我们要做的,是让操作者知道发生了什么事情,而不是直截了当的结束程序,这时我们就用到了异常处理(

  • JAVA自定义异常使用方法实例详解

    定义三种新类型的异常. 写一个类,在该类的三个方法中抛出三种不同的异常. 然后在mian方法中调用这个类的不同方法,尝试用try catch捕获你写的异常. public class Work2 { public static void main(String[] args) { ExceptionGenerator exceptionGenerator = new ExceptionGenerator(); //处理第一种自定义编译时异常 try { exceptionGenerator.ge

  • java自定义异常以及throw和throws关键字用法

    java中内置了很多可能在编程时出现的大部分异常.除此之外,用户可以使用一个类继承Exception类即可继承自定义类异常. 在程序中自定义类,大体上分为以下几个步骤: 1.创建自定义异常类 2.在方法中通过throw关键字抛出异常对象. 3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句块捕捉并处理异常,否则在方法的声明处通过throws指明要抛出给方法调用者的异常,继续进行下一步操作. 4.再出现异常的方法的调用者中捕获处理异常. 下面是我创建自定义异常.在项目中创建类M

  • 浅谈JAVA在项目中如何自定义异常

    JAVA项目中自定义异常 1.数据返回处理类 @Data public class R<T> implements Serializable { private static final long serialVersionUID = -8497670085742879369L; @ApiModelProperty(value = "返回码", example = "200") private Integer code=200; @ApiModelPro

  • Java如何自定义异常打印非堆栈信息详解

    前言 在学习Java的过程中,想必大家都一定学习过异常这个篇章,异常的基本特性和使用这里就不再多讲了.什么是异常?我不知道大家都是怎么去理解的,我的理解很简单,那就是不正常的情况,比如我现在是个男的,但是我却有着女人所独有的东西,在我看来这尼玛肯定是种异常,简直不能忍.想必大家都能够理解看懂,并正确使用. 但是,光学会基本异常处理和使用不够的,在工作中出现异常并不可怕,有时候是需要使用异常来驱动业务的处理,例如: 在使用唯一约束的数据库的时候,如果插入一条重复的数据,那么可以通过捕获唯一约束异常

  • java简单自定义异常实例代码

    此处主要便于对异常类的使用上,方便大家理解,以一个公约数为例做了一个简单自定义异常的处理代码如下: 如果操作者输入数字符合要求程序运行,不符合则抛出错误. package 自定义异常简单实例; import java.util.Scanner; public class CommonDivisor { static Scanner in; public void gongyue(int m,int n) throws Exception{ if(m<0||n<0) { throw new Ex

  • Java如何实现自定义异常类

    这篇文章主要介绍了Java如何实现自定义异常类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 自定义异常类步骤 创建一个类继承异常父类Exception 在具体的实现方法首部抛出异常类(自己创建的那个类),throws的运用 在具体的实现方法的内部抛出异常信息,throw的运用 创建一个类继承异常父类Exception public class EmailException extends Exception { EmailException(

  • Java自定义异常与异常使用的最佳方式

    目录 异常的分类 1. 非运行时异常(Checked Exception) 2. 运行时异常(Runtime Exception/Unchecked Exception) 异常的处理 一.对应非运行时异常,必须对其进行处理 二.对于运行时异常,可以不对其进行处理 应用场景 自定义异常类过程 1. 多数情况下 扩展: 2. 声明方法抛出自定义异常 3.自定义异常测试操作 使用异常的最佳实践 1. 记得释放资源 2. 不要使用异常作控制流程之用 3. 不要忽略异常 4. 不要 catch 最高层次的

  • Java虚拟机处理异常的最佳方式

    前言 欢迎来到Under The Hood专栏.本专栏旨在让Java开发人员一瞥在运行Java程序底层的神秘机制.本月的文章继续讨论Java虚拟机的字节码指令集,方法是检查Java虚拟机处理异常抛出和捕获的方式,包括相关的字节码.本文不讨论finally条款 - 这是下个月的主题.后续文章将讨论字节码系列的其他成员. 下面话不多说了,来一起看看详细的介绍吧 Exceptions Exceptions允许您顺利处理程序运行时发生的意外情况.要演示Java虚拟机处理异常的方式,请考虑一个名为NitP

  • 浅谈RxJava处理业务异常的几种方式

    本文介绍了RxJava处理业务异常的几种方式,分享给大家.具体如下: 关于异常 Java的异常可以分为两种:运行时异常和检查性异常. 运行时异常: RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过. 检查性异常: 除了RuntimeException及其子类以外,其他的Exception类及其子类都属于检查性异

  • Java中的异常和处理机制实例详解

    本文实例讲述了Java中的异常和处理机制.分享给大家供大家参考,具体如下: 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. Java提供了更加优秀的解决办法:异常处理机制. 异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰. Java中的异常可以是函数中的

  • 详解Java的Exception异常机制

    一.前言 在Java中,我们在执行代码的过程中难免会遇到错误与Exception异常,可是我们一直都是锤头Coding而忽略了学习Exception这个东西!我们只是知道在发生Exception的地方让代码自动生成throw exception或者是使用try-catch括起来处理,那你了解Java的Exception吗?今天就让我们把一起来看看Java的Exception吧! 在Java中,我们的代码再出现错误的时候无非是两种情况:一是Error,一是异常Exception.如果是Error,

  • Python中的异常类型及处理方式示例详解

    目录 前言 正文 一.什么是异常 二.异常的类型 三.异常处理 四.try 介绍 五.finally 介绍 六.raise 介绍 结尾 前言 Python 是一种面向对象的.解释型的.通用的.开源的脚本编程语言.现在市面上 Python 非常的流行,主要是因为它简单易用,学习成本低,比如要实现某个功能,Python 可能只需要几行代码,而用C语言可能需要上百行代码,因为C语言什么都要得从头开始编码,而 Python 已经内置了很多功能模块,所以,我们只需要导入特定的包,就可以实现想要的效果. 正

  • Java:详解Java中的异常

    目录 Java异常 常见异常 throw和throws的区别 final.finally.finalize的区别 总结 Java异常 Java中的异常:又称例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流 异常的分类:Throwable:类是java语言中所有错误或异常的超类,这意味着只要指示错误或异常,那么肯定是thrawble子类的实例,但是事实上由于错误异常内容过于庞大,所以设计人员将它们分开来,这就是thrawble的两个子类,Error和Exception Erro

  • Java 数组转List的四种方式小结

    目录 第一种方式(未必最佳):使用ArrayList.asList(strArray) 第二种方法(支持增删查改): 第三种方式(通过集合工具类Collections.addAll()方法(最高效)) 第四种方式通过JDK8的Stream流将3总基本类型数组转为List java数组转list误区 一.不能把基本数据类型转化为列表 二.asList方法返回的是数组的一个视图 第一种方式(未必最佳):使用ArrayList.asList(strArray) ​ 使用Arrays工具类Arrays.

  • springboot处理异常的5种方式

    目录 1.自定义错误页面 2.@ExceptionHandle 注解处理异常 3.@ControllerAdvice+@ExceptionHandler 注解处理异常 4.配置 SimpleMappingExceptionResolver 处理异常 5.自定义 HandlerExceptionResolver 类处理异常 通用异常处理: 1.自定义异常枚举类 2.自定义异常类 3.自定义异常结果处理类 4.全局异常处理 程序的异常:Throwable 严重错误问题:Error     我们不处理

  • Java处理InterruptedException异常的理论与实践

    前言 对于 InterruptedException,一种常见的处理方式是 "生吞(swallow)" 它 -- 捕捉它,然后什么也不做(或者记录下它,不过这也好不到哪去)-- 就像后面的 清单 4 一样.不幸的是,这种方法忽略了这样一个事实:这期间可能发生中断,而中断可能导致应用程序丧失及时取消活动或关闭的能力. 阻塞方法 当一个方法抛出 InterruptedException 时,它不仅告诉您它可以抛出一个特定的检查异常,而且还告诉您其他一些事情.例如,它告诉您它是一个阻塞(bl

随机推荐