1.异常的传播

当某个方法抛出异常时:

  • 如果当前方法没有捕获,异常就被抛到上层调用方法
  • 直到遇到某个try...catch被捕获
  • 使用printStackTrace()打印处方法的调用栈
import java.lang.String;

public class Main {
public static void main(String[] args) {
try{
process1();
}catch (Exception e){
e.printStackTrace();//对于调试错误非常有用
}
}
static void process1(){
process2();
}
static void process2() {
Integer.parseInt(null);
}
}

2.抛出异常

  • 创建某个Exception的实例
  • 用throw语句抛出
import java.lang.String;

public class Main {
public static void main(String[] args) {
try{
process1("");
}catch (Exception e){
e.printStackTrace();
}
}
static void process1(String s){
throw new IllegalArgumentException();
}
}

3.转换异常与持有原有异常

3.1转换异常

如果一个方法捕获了某个异常后,又在catch子句中抛出新的异常,就相当与把抛出的异常类型“转换”了。

import java.lang.String;

public class Main {
public static void main(String[] args) {
process1("");
}
static void process1(String s){
try{
process2(s);
}catch (NullPointerException e){
throw new IllegalArgumentException();//捕获NullPointerException,抛出IllegalArgumentException
}
}
static void process2(String s){
throw new NullPointerException();
}
}


## 3.2转换的异常持有原有异常
上例中存在的问题:新的异常丢失了原始异常信息,只追踪到process1。如何让新的Exception可以持有原始异常信息?
解决方法:将异常传入即可。
throw new IllegalArgumentException(e);
```#java
import java.lang.String;

public class Main {

public static void main(String[] args) {

process1("");

}

static void process1(String s){

try{

process2(s);

}catch (NullPointerException e){

throw new IllegalArgumentException(e);

}

}

static void process2(String s){

throw new NullPointerException();

}

}

<img src="https://img2018.cnblogs.com/blog/1418970/201901/1418970-20190129145215827-451969646.png" width="700" />

#    4.被屏蔽的异常suppressed exception
在抛出异常前,finally语句会保证执行。
<font color=#9400D3>如果finally语句抛出异常,则catch语句不再抛出,没有被抛出的异常被称为“被屏蔽”的异常(suppressed exception)</font>
```#java
import java.lang.String; public class Main {
public static void main(String[] args) {
try{
process1("");
}catch (Exception e){
System.out.println("catched");
throw new RuntimeException(e);//“被屏蔽”的异常(suppressed exception)
}finally {
System.out.println("finally");
//throw new NullPointerException();
}
}
static void process1(String s){
throw new IllegalArgumentException();
}
}

finally中不抛出异常



finally中抛出异常

throw new NullPointerException();去掉注释



因此尽量避免在finally中抛出异常

5.如何保存所有的异常信息

  • 使用origin变量保存原始异常
  • 如果存在原始异常,用addSuppressed()添加新异常
  • 如果存在原始异常,或者新异常,最后在finally抛出
import java.lang.String;

public class Main {
public static void main(String[] args) throws Exception {
Exception origin = null;
try{
process1("");
}catch (Exception e){
origin = e;
System.out.println("catch捕捉到了");
throw new RuntimeException("可能屏蔽的异常"+e);
}finally {
System.out.println("finally");
try{
throw new NullPointerException("finally 抛出的异常");
}catch (Exception e){
if (origin != null ){
origin.addSuppressed(e);
}else{
origin = e;
}
}
if (origin != null){
throw origin;
}
}
}
static void process1(String s){
throw new IllegalArgumentException("process1方法异常了,32");
}
}


## 5.2获取所有的异常信息
因为一般不在finally中捕获异常,所以可以直接使用for循环将异常信息打印出来。
```#java
import java.lang.String;

public class Main {

public static void main(String[] args) throws Exception {

Exception origin = null;

try{

process1("");

}catch (Exception e){

e.printStackTrace();

for(Throwable t:e.getSuppressed()){

t.printStackTrace();

}

}finally {

System.out.println("finally");

}

}

static void process1(String s){

throw new IllegalArgumentException("process1方法异常了,32");

}

}

<img src="https://img2018.cnblogs.com/blog/1418970/201901/1418970-20190129173524625-1932720916.png" width="700" />

#    6.总结:
* printStackTrace()可以打印异常的传播栈,对于调试非常有用
* 捕获异常并再次抛出新的异常时,应该持有原有异常信息。即新抛出的异常应该包含原始异常。
* 如果在finally中抛出异常,应该把新抛出的异常添加到原有异常中
* 用getSuppressed()可以获取所有添加的Suppressed Exception
* 处理Suppressed Exception要求JDK>= 1.7

廖雪峰Java3异常处理-1错误处理-3抛出异常的更多相关文章

  1. 廖雪峰Java3异常处理-1错误处理-2捕获异常

    1捕获异常 1.1 finally语句保证有无错误都会执行 try{...}catch (){...}finally{...} 使用try...catch捕获异常 可能发生异常的语句放在try{... ...

  2. 廖雪峰Java3异常处理-1错误处理-1Java的异常

    1.计算机运行中的错误 在计算机程序运行的过程中,错误总会出现,不可避免的 用户输入错误 读写文件错误 网络错误.内存耗尽.无法连接打印机不可 String s = "abc"; ...

  3. 廖雪峰Java3异常处理-1错误处理-4自定义异常

    JDK已有的异常: RuntimeException * NullPointerException * IndexOutOfBoundsException * SecurityException * ...

  4. 廖雪峰Java3异常处理-2断言和日志-3使用Commons Logging

    Commons Logging是Apache创建的日志模块: 可以挂接不同的日志系统 可以通过配置文件指定挂接的日志系统 自动搜索并使用Log4j 如果Log4j不存在,使用JDK Logging(J ...

  5. 廖雪峰Java3异常处理-2断言和日志-1使用断言

    1.断言 断言Assertion是一种程序调试方式 使用assert关键字 断言条件预期为true 如果断言失败,抛出AssertionError,停止程序 可选的断言消息,断言失败,就会抛出 pub ...

  6. 廖雪峰Java3异常处理-2断言和日志-4使用Log4j

    1.Log4j Log4j是目前最流行的日志框架.有两个版本 1.x:Log4j 2.x:Log4j2 Log4j下载地址https://www.apache.org/dyn/closer.lua/l ...

  7. 廖雪峰Java3异常处理-2断言和日志-2使用JDK Logging

    1.日志 为了取代System.out.println() 可以设置输出样式 可以设置输出级别,禁止某些级别输出 可以被重定向到文件 可以按包名控制日志级别 2.JDK内置Logging 在java. ...

  8. 廖雪峰Java-3流程控制-7for循环

    for循环 for循环使用计数器实现循环 for循环条件需要设置:计数器初始值:循环前检测条件:每次循环后如何更新计数器 计数器变量通常命名为i int[] ns = {1,4,9,16,25}; f ...

  9. 爬虫:把廖雪峰的教程转换成 PDF 电子书

    写爬虫似乎没有比用 Python 更合适了,Python 社区提供的爬虫工具多得让你眼花缭乱,各种拿来就可以直接用的 library 分分钟就可以写出一个爬虫出来,今天就琢磨着写一个爬虫,将廖雪峰的 ...

随机推荐

  1. JAVA中native方法调用

    在Java中native是关键字.它一般在本地声明,异地用C和C++来实现.它的声明有几点要注意:1)native与访问控制符前后的关系不受限制.2)必须在返回类型之前.3)它一般为非抽象类方法.4) ...

  2. Ubuntu防火墙简单设置

    http://wiki.ubuntu.org.cn/UFW防火墙简单设置 http://wiki.ubuntu.org.cn/Ufw使用指南 Ubuntu默认安装内置ufw防火墙,简单使用如下: su ...

  3. python str使用笔记(更新)

    判断字符串是否以某个串为结尾: str.endswith(strtmp) 返回True/False >>> strs='aba' >>> strs.endswith ...

  4. webpack执行命令参数

    在webpack执行命令之后可以添加一些参数,这些参数都有自己的作用,下面是参数列表: $ webpack --config XXX.js //使用另一份配置文件(比如webpack.config2. ...

  5. EXtJS Ext.data.Model

    (一).首先我们介绍一下Model类中比较常用的几个属性,如果我们想构建一个Model类,最主要的属性就是(Fields)属性,这个属性接受一个数组.用来设置Model中所包含的字段.定义的格式如下: ...

  6. 在WinForm中使用Web Services 来实现 软件自动升级( Auto Update ) (C#)

    winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了 ...

  7. js 时间戳和日期互转

    // 获取当前时间戳(以s为单位) var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; //当前时间戳为:140 ...

  8. RTP RTCP RTSP

    1.RTP  over UDP和RTP over RTSP有什么区别?2.RTP over RTSP是不是就是RTP over TCP?3.RTP over TCP 打包视频是不是要加4个字节的头,是 ...

  9. linux shell写入单行、多行内容到文件

    1.单行文本 #! /bin/bashecho 'hello world' > filename.txt 2.多行文本 代码1: #! /bin/bashcat>filename.txt& ...

  10. MapReduce案例:统计共同好友+订单表多表合并+求每个订单中最贵的商品

    案例三: 统计共同好友 任务需求: 如下的文本, A:B,C,D,F,E,OB:A,C,E,KC:F,A,D,ID:A,E,F,LE:B,C,D,M,LF:A,B,C,D,E,O,MG:A,C,D,E ...