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. MySQL数据库安装和介绍

    一.概述 1.什么是数据库 ? 答:数据的仓库,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 答:他们均是一种软件,都有两个主要的功 ...

  2. Go Example--结构体

    package main import "fmt" //定义一个私有结构体 type person struct { name string age int } func main ...

  3. SPOJ NSUBSTR Substrings

    题意 dt { font-weight: bold; margin-top: 20px; padding-left: 35px; } dd { box-shadow: 3px 3px 6px #888 ...

  4. <--------------------------常用的API方法------------------------------>

    //1.int length(): 返回的是字符串的长度 public static void fun1() { String string = "string"; int i = ...

  5. Singer 开源便捷的ETL 工具

    singer 是一个强大,灵活的etl 工具,我们可以方便的提取web api,file,queue,基本上各种你可以想到的 数据源. singer 有一套自己的数据处理规范, taps, targe ...

  6. Power consumption comparison

    Here is my draft evaluation when old MCU replacement for power consumption, the comparsion betwween ...

  7. 13机器学习实战之PCA(1)

    降维技术 对数据进行降维有如下一系列的原因: 使得数据集更容易使用 降低很多算法的计算开销 去除噪音 使得结果易懂 在以下3种降维技术中, PCA的应用目前最为广泛,因此本章主要关注PCA. 主成分分 ...

  8. [转] VS2017 打包安装程序

    前言 C#写好一个应用程序,总想分享给自己的朋友或者上架,然而被困在打包之外,这次为大家带来近期我的经验,经过几天的摸索,发现网上的教程并不全面,会给初学者带来很多疑问,这里将做些问题描述与解答. / ...

  9. [转]AJAX 简介

    AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 您应当具备的基础知识 在继续学习之前,您需要对下面的知识有基本的了解: HTML / XHTML CSS JavaScript ...

  10. python ord()与chr()用法以及区别

    ord()函数主要用来返回对应字符的ascii码,chr()主要用来表示ascii码对应的字符他的输入时数字,可以用十进制,也可以用十六进制. >>> ord("a&quo ...