Java异常链需显式传入cause,单参构造函数仅接收String,双参构造或特定Exception子类的单参构造才支持cause;自定义异常须调用super(cause)或super(message, cause),initCause()风险高且受限。
Java中
的链式构造必须显式传入
Java异常链不是自动建立的,不手动传参就不会保留原始异常。哪怕你用
,如果
是
类型,它也不会自动成为
——因为
的单参构造函数是把参数当
用的,不是当
。
必须用双参构造:
或
(仅限
子类的单参构造,且该构造明确声明接受
)
和
的单参构造只接收
,传
进去会调用
转成消息,原始堆栈彻底丢失
自定义异常要支持链式,必须在构造函数里显式调用
或
哪些构造函数真正支持
?看JDK源码最准
别靠名字猜,比如
有,但
没有(JDK 17之前根本不存在这个重载)。常见误区是以为“带
参数就一定设
”,其实得看具体签名和实现。
标准做法:优先用
形式,兼容性最好
慎用无
的单
构造——很多类没提供,或行为不一致(如
根本不支持设
)
检查方法:点进IDE里的构造函数声明,看参数类型是不是
,且
java
doc是否写明“the cause”
用
补救?风险很大
这个方法只在
为
时才允许调用一次,而且不能在构造过程中用(因为父类构造未完成),更不能对已设过
的实例再调。实际场景中几乎没机会安全使用。
典型误用:
放在
块里,但
可能已在构造时设过
,此时抛
它不改变
的输出结构,但会让
返回值不稳定(取决于是否成功调用)
替代方案更可靠:直接重构为用双参构造新建异常
日志和调试时,
可能返回
,但不代表没链
有些框架(如Spring AOP代理、某些RPC客户端)会在包装异常时漏掉
传递,或者用
机制代替链式。这时候
是
,但原始异常其实在
里,或藏在
里被字符串化了。
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
立即学习
“
Java免费学习笔记(深入)
”;
排查链断裂:用
看完整堆栈,比只查
更靠谱
记录日志时别只打
,要用
这种带
参数的重载
自定义异常若重写了
或
,务必确保不覆盖
信息
异常链不是写个
就完事的,每个构造函数的行为差异、每个框架的包装逻辑、每次日志输出的方式,都会悄悄吃掉原始异常。留心那些没报错但堆栈突然变短的时刻——那往往就是链断了。
Throwablecausethrow new RuntimeException(e)eExceptioncauseRuntimeExceptionmessagecausenew RuntimeException("msg", e)new RuntimeException(e)ExceptioncauseErrorRuntimeExceptionStringExceptiontoString()super(cause)super(message, cause)causeIllegalArgumentException(String, Throwable)IllegalArgumentException(Throwable)Throwablecausenew XxxException(message, cause)messagecauseNullPointerExceptioncauseThrowableinitCause()causenullcauseex.initCause(originalEx)catchexcauseIllegalStateExceptionprintStackTrace()getCause()getCause()nullcauseSuppressedgetCause()nullgetSuppressed()detailMessageThrowable.printStackTrace()getCause()e.getMessage()org.slf4j.Logger.error(String, Throwable)ThrowabletoString()getMessage()causethrow new Xxx(e)