异常的概念和Java异常体系结构

异常是程序运行过程中出现的错误。本文主要讲授的是Java语言的异常处理。Java语言的异常处理框架,是Java语言健壮性的一个重要体现。

Thorwable类所有异常和错误的超类,有两个子类ErrorException,分别表示错误和异常。
其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常,这两种异常有很大的区别,也称之为不检查异常(Unchecked Exception)
和检查异常(Checked Exception)。

  • 运行时异常 ---> UncheckedException
  • 非运行时异常--->CheckedException

Error和 Exception

  • Error是程序无法处理的错误,比如OutOfMemoryErrorThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

  • Exception是程序本身可以处理的异常,这种异常分两大类,运行时异常非运行时异常。程序中应当尽可能去处理这些异常。

2、运行时异常和非运行时异常

运行时异常都是RuntimeException类及其子类异常,如

  • NullPointerException、
  • IndexOutOfBoundsException

这些异常是不检查异常(UncheckedException),程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。编译是可以通过的

非运行时异常是除RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

异常的捕获和处理

Java异常的捕获和处理是一个不容易把握的事情,如果处理不当,不但会让程序代码的可读性大大降低,而且导致系统性能低下,甚至引发一些难以发现的错误。

Java异常处理涉及到五个关键字,分别是:trycatchfinallythrowthrows

try、catch、finally三个语句块应注意的问题

trycatchfinally三个语句块均不能单独使用,三者可以组成 try...catch...finallytry...catchtry...finally三种结构,catch语句可以有一个或多个,finally语句最多一个。
try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些块的外面。
多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下。

throw、throws关键字

throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。

如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。
如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。有关异常的转译会在下面说明。

当抛出的是运行时异常,程序可以选择处理和不处理

public static void main(String[] args) {
try {
FileReader file = new FileReader("d:/entitycode");
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException();
}
}

抛出的是非运行时异常时,程序必须要处理,可以继续往外抛,或者捕获

public static void main(String[] args) throws FileNotFoundException {
try {
FileReader file = new FileReader("d:/entitycode");
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new FileNotFoundException();
}
}
throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理。下面给出一个简单例子,

Throwable类中的常用方法

  • getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。
  • getMessage():返回异常的消息信息。
  • printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。

异常处理的一般原则

能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。因为对于一个应用系统来说,抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地――可处理也可不处理。
对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。

Java异常总结

Java将异常区分为Error与Exception,Error是程序无力处理的错误,Exception是程序可以处理的错误。异常处理是为了程序的健壮性。
异常能处理就处理,不能处理就抛出,最终没有处理的异常JVM会进行处理。
异常可以传播,也可以相互转译,但应该根据需要选择合理的异常转译的方向。
对于一个应用系统,设计一套良好的异常处理体系很重要。这一点在系统设计的时候就应该考虑到。
Exception一般分为Checked异常Runtime异常,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException

Spring事务回滚与异常

Spring被事务管理的方法,需要抛出非检查异常,即运行期异常才能进行回滚

对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。所以必须在service捕获异常,然后再次抛出,这样事务方才起效。

在spring的事务管理环境下,使用unckeckedException可以极大地简化异常的处理,只需要在事务层声明可能抛出的异常(这里的异常可以是自定义的unckecked exception体系),在所有的中间层都只是需要简单throws即可,不需要捕捉和处理,直接到最高层,比如UI层再进行异常的捕捉和处理

在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked如果遇到checked意外就不回滚。

如何改变默认规则:

  • 1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

  • 2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

  • 3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。

一个统一的异常层次结构对于提供服务抽象是必需的。 最重要的就是org.springframework.dao.DataAccessException以及其子类了。 需要强调的是Spring的异常机制重点在于应用编程模型。与SqlException和其他数据存取API不同的是: Spring的异常机制是为了让开发者使用最少, 最清晰的代码。DataAccessException和其他底层异常都是非检查性异常(unchecked exception)。 spring的原则之一就是基层异常就应该是非检查性异常. 原因如下:

  • 基层异常通常来说是不可恢复的。
  • 检查性异常将会降低异常层次结构的价值.如果底层异常是检查性的, 那么就需要在所有地方添加catch语句进行捕获。
  • try/catch代码块冗长混乱,而且不增加多少价值。使用检查异常理论上很好, 但是实际上好象并不如此。Hibernate3也将从检查性异常转为非检查性异常。

转自:https://www.cnblogs.com/leihuazhe/p/7735416.html

【转】Java异常总结和Spring事务处理异常机制浅析的更多相关文章

  1. Java异常总结和Spring事务处理异常机制浅析

    异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,是Java语言健壮性的一个重要体现. Thorwable类所有异常 ...

  2. 从源码解析 Spring JDBC 异常抽象

    初入学习 JDBC 操作数据库,想必大家都写过下面的代码: 数据库为:H2 如果需要处理特定 SQL 异常,比如 SQL 语句错误,这个时候我们应该怎么办? 查看 SQLException 源码,我们 ...

  3. spring+ibatis问题1—— 程序报错:java.sql.SQLException: Io 异常: Connection reset by peer, socket write error; ”或“java.sql.SQLException 关闭的连接”异常

    转自:http://blog.sina.com.cn/s/blog_1549fb0710102whz2.html spring+ibatis程序测试时报错:java.sql.SQLException: ...

  4. 【Java Web开发学习】Spring MVC异常统一处理

    [Java Web开发学习]Spring MVC异常统一处理 文采有限,若有错误,欢迎留言指正. 转载:https://www.cnblogs.com/yangchongxing/p/9271900. ...

  5. Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...

  6. java 之DelayQueue,TaskDelayed,handlerFactory,dataChange消息配置.收发等.java spring事务处理TransactionTemplate

    java 之DelayQueue,TaskDelayed,handlerFactory,dataChange消息配置.收发等.java spring事务处理TransactionTemplate等. ...

  7. spring mvc 异常统一处理方式

    springMVC提供的异常处理主要有两种方式: 一种是直接实现自己的HandlerExceptionResolver: 另一种是使用注解的方式实现一个专门用于处理异常的Controller——Exc ...

  8. Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-异常模块的设计与架构(源码可下载) 说明:任何一个软件系统都会出现各式各样的异常与错误,我们需要根据异常的情况进行捕获与分析,改善自己的代码,让其更加的稳定的,快速的运行,那 ...

  9. 《深入理解Java虚拟机》-----第2章 Java内存区域与内存溢出异常

    2.1 概述 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任 ...

随机推荐

  1. 【AtCoder】CODE FESTIVAL 2017 qual C

    A - Can you get AC? No #include <bits/stdc++.h> #define fi first #define se second #define pii ...

  2. springboot+thymeleaf简单使用

    关于springboot想必很多人都在使用,由于公司项目一直使用的是SpringMVC,所以自己抽空体验了一下springboot的简单使用. 环境搭建 springbooot的环境搭建可以说很灵活, ...

  3. Gitlab管理用户、组、权限(一)

    && 内容: 添加用户 创建组 用户权限 保护主要分支 配置项目的可见性 移除用户 一. 添加用户 1. 用root 管理员登陆. 2. 点击管理区域 3. 点击New User 4. ...

  4. (转)final修饰基本类型和引用类型变量的区别

    原文:http://blog.csdn.net/linhao19891124/article/details/52971045 当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本 ...

  5. Visual Studio Code-GO tasks 设置 (实现在vsc下直接编译输出的功能)

    Visual Studio Code -GO 使用过程中发现,如果要编译输出某个文件需要去cmd窗口才行,感觉特别麻烦网上一直没找到解决办法,这几天查看Visual Studio Code文档发现它提 ...

  6. VUE3.0升级与配置(跨域、全局scss变量等)

    1.检查本机vue版本 vue -V 2.升级vue3.0命令 npm install -g @vue/cli 3.创建完项目后,在项目根目录新增vue.config.js文件,插入代码(简洁) mo ...

  7. VB.NET 编程元素支持更改总结

    Visual Basic 2005 更改了它支持各种编程元素的方式,主要是为了提供与公共语言运行库的互操作性.许多 Visual Basic 6.0 元素被重新命名,重新分类或与 Visual Bas ...

  8. Javascript日常编码中的一些常见问题

    一.尽量少用全局变量   这是一个疑问最少,同时流传最 广的一条.Javascript使用函数管理作用域,全局变量最大的问题在于同名变量冲突.这种隐患产生比较直接的两个原因就是Javascript语言 ...

  9. windows系统,添加网络位置向导。

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha ============ 创建一个文件夹 共享. 共享位置 ,文件夹 图标 修改. 分组 ...

  10. Codeforces.911F.Tree Destruction(构造 贪心)

    题目链接 \(Description\) 一棵n个点的树,每次可以选择树上两个叶子节点并删去一个,得到的价值为两点间的距离 删n-1次,问如何能使最后得到的价值最大,并输出方案 \(Solution\ ...