Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 323|回复: 0

java异常——重新抛出异常

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-14 02:06:07 | 显示全部楼层 |阅读模式

    有时候希望把刚捕获的异常重新抛出,尤其是在使用Exception捕获所有异常的时候。既然已经得到了对当前异常对象的引用,可以直接把它重新抛出:

    catch(Exception e){
    System.out.println("an exception was thrown");
    throw e;
    }
    

    重新抛出异常会把异常抛给上一级环境中的异常处理程序,同一个try块的后续catch子句将会被忽略。此外,异常对象的所有信息都得以保持,所以高一级环境中捕获此异常的处理程序可以从这个异常对象中得到所有信息。
    如果只是把当前异常对象重新抛出,那么printStackTrace()方法显示的将是原来异常抛出的调用栈信息,而非重新抛出点的信息。要向更新这个信息,可以调用filStackTrace()方法,这将返回一个Throwable对象,它是通过把当前调用栈信息填入原来那个异常对象而建立的,就像这样:

    public class Rethrowing {

    public static void f() throws Exception {
    	System.out.println("a_mark");
    	throw new Exception("b_mark");
    }
    
    public static void g() throws Exception {
    	try {
    		f();
    	} catch (Exception e) {
    		System.out.println("c_mark");
    		e.printStackTrace(System.out);
    		throw e;
    	}
    }
    
    public static void h() throws Exception {
    	try {
    		f();
    	} catch (Exception e) {
    		System.out.println("d_mark");
    		e.printStackTrace(System.out);
    		throw (Exception) e.fillInStackTrace();
    	}
    }
    
    public static void main(String[] args) {
    	try {
    		g();
    	} catch (Exception e) {
    		System.out.println("e_mark");
    		e.printStackTrace(System.out);
    	}
    
    	System.out.println("\n-------------between line--------------------\n");
    
    	try {
    		h();
    	} catch (Exception e) {
    		System.out.println("f_mark");
    		e.printStackTrace(System.out);
    	}
    }
    

    }
    /*输出如下:

    a_mark
    c_mark
    java.lang.Exception: b_mark
    at testThread.Rethrowing.f(Rethrowing.java:7)
    at testThread.Rethrowing.g(Rethrowing.java:12)
    at testThread.Rethrowing.main(Rethrowing.java:32)
    e_mark
    java.lang.Exception: b_mark
    at testThread.Rethrowing.f(Rethrowing.java:7)
    at testThread.Rethrowing.g(Rethrowing.java:12)
    at testThread.Rethrowing.main(Rethrowing.java:32)

    -------------between line--------------------

    a_mark
    d_mark
    java.lang.Exception: b_mark
    at testThread.Rethrowing.f(Rethrowing.java:7)
    at testThread.Rethrowing.h(Rethrowing.java:22)
    at testThread.Rethrowing.main(Rethrowing.java:41)
    f_mark
    java.lang.Exception: b_mark
    at testThread.Rethrowing.h(Rethrowing.java:26)
    at testThread.Rethrowing.main(Rethrowing.java:41)

    */

    调用filStackTrace()的那一行就成了异常的重新发生地了。
    有可能在捕获异常之后抛出另一种异常。这么做的话,得到的效果类似于使用filStackTrace(),有关原来异常发生的信息会丢失,剩下的是与新的抛出点有关的信息:

    class OneException extends Exception {
    public OneException(String s) {
    super(s);
    }
    }

    class TwoException extends Exception {
    public TwoException(String s) {
    super(s);
    }
    }

    public class RethrowNew {

    public static void f() throws OneException {
    	System.out.println("a_mark");
    	throw new OneException("thrown from f()");
    }
    
    public static void main(String[] args) {
    	try {
    		try {
    			f();
    		} catch (Exception e) {
    			System.out.println("b_mark");
    			e.printStackTrace(System.out);
    			throw new TwoException("from inner try");
    		}
    	} catch (Exception e) {
    		System.out.println("c_mark");
    		e.printStackTrace(System.out);
    	}
    }
    

    }

    最后那个异常仅知道自己来自 main(),而对 f() 一无所知。
    永远不必为清理前一个异常对象而担心,或者说为异常对象的清理而担心。他们都是用 new 在堆上创建的对象,所以gc会自动把他们清理掉。

    备:throw 与 throws 之区分
    throw 是语句抛出一个异常,该语句用在方法体内,表示抛出异常,由方法体内的语句处理。
    throws 是方法可能抛出异常的声明,该语句用在方法声明后面,表示再抛出异常,由该方法的调用者来处理。

    ////end

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-3 13:01 , Processed in 0.053384 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表