惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
D
Docker
C
Cyber Attacks, Cyber Crime and Cyber Security
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
Google DeepMind News
Google DeepMind News
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
The Hacker News
The Hacker News
Project Zero
Project Zero
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Vercel News
Vercel News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Scott Helme
Scott Helme
A
About on SuperTechFans
WordPress大学
WordPress大学
F
Fortinet All Blogs
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security

博客园 - FallingAutumn

mysql常用命令集锦 Java ClassLoader加载机制理解 实际例子 Java ClassLoader加载机制理解 myeclipse 8.5破解方法 Replace Pioneer 试用推广 JAVA RMI调用实战学习 linux下关于压缩、解压相关的操作 关于hessian接口类方法顺序及对象序列化的实战研究 Java对象引用传递探索 mysql 语句or效率问题 log4j配置详解 vs2005 sp1补丁安装,报1718错误: 数字签名拒绝 无法访问Windows Installer服务 之错误解决 打开word时,”无法注册这篇文档,不能创建从其他文档到这篇文档的链接“ 错误的解决 Oracle中DBMS_JOB.SUBMIT的用法说明 vs2008 sp1如何修复、删除以及增加组件的方法 OCI-22053: 溢出错误 的原因和解决方案 statspack的实战学习 - FallingAutumn - 博客园 ORACLE中,Schema的理解
Java异常学习总结
FallingAutumn · 2013-06-07 · via 博客园 - FallingAutumn

一、官方API对此的解释: 

1、Throwable:异常和错误的基类,提供了错误堆栈实现等一系列方法。 两个直接子类: Error & Exception

2、两个子类区别:

     Error: 程序不应该捕捉的错误,应该交由JVM来处理。一般可能指非常重大的错误。

     Exception:程序中应该要捕获的错误。

     RuntimeException:运行期异常,是Exception的子类,但勿需捕捉的异常超类

二、各自代码中的表象  

Error & RuntimeException:不需要异常处理的,即无try/catch or throws的,编译器认可此种方式;

Exception(排除RuntimeException):编译器强制要求做异常处理的,即必须要 try/catch or throws的;

进一步解释: Exception分为checked Exception & unchecked Exception两种,

                  unchecked Exception指勿须检查的异常,也即RuntimeException/Error,运行期错误JVM来打理;

                  checked Exception指必须处理的异常,否则编译器就不让过;

三、为何这样设计?    

如上述,Throwable存在2种维度的设计: 1、是否checked  2、 异常级别

是否checked: 表象很明显,编译器会强制检测;

异常级别: 分为 错误和异常,可这个如何来区分呢?我确实很困惑,应该是个人理解的把握了。

四、异常常用关键点知识

1、保留异常源头

    异常处理是层级追溯机制,因此异常可被多次抛出,但只要不改变源异常的句柄及其stackTrace,就可一直保留异常源头。

    也即简单的throw e(最初的那个异常),异常源头依旧被保留。

2、改变异常源头

    如果想改变异常源头,通过抛出一个新异常或在层级机制处理中改变其stackTrace即可。

    如在调用方法中e.fillStackTrace() or throw new Excepiton("...")即可定位当前方法为异常源头。

3、自定义异常

     一般来说,自定义异常多以checked的为主,也即从Exception继承,实现非常简单,复杂度就看业务需要了,就不多说了。

4、附上部分代码,参照Thinking in java中的实现 

public class ThrowableExceptionStudy {    
    // 异常测试
    public static void main(String[] args) throws InterruptedException {        
        reThrowTest();  // 异常重新抛出测试(可控制改变源头)
        rethrowNew();  // 抛出一个新异常测试(改变源头)
        runtimeExceptionTest(); // 运行期异常测试
        errorTest();  // error测试
    }
    
    /**
     * 异常重新抛出测试
     */
    private static void reThrowTest() {
        try {
            g();
        } catch (Exception e) { // 抛出Exception
            System.out.println("Caught exception in reThrowTest, e.printStackTrace()");
            e.printStackTrace();
        } catch    (Throwable t) { // 抛出Throwable
            System.out.println("Caught throwable in reThrowTest, t.printStackTrace()");
            t.printStackTrace();
        }
    }

    /**
     * 异常源头
     */
    private static void f() throws Exception {
        System.out.println("originating the exception in f()");
        throw new Exception("thrown from f()");
    }

    /**
     * 异常重新抛出,不改变异常句柄
     * 以两种方式抛出:1、不改变异常源头 2、改变异常源头
     */
    private static void g() throws Throwable {
        try {
            f();
        } catch (Exception e) {
            System.out.println("Inside g(), e.printStackTrace()");
            e.printStackTrace();
            //throw e; // a: 不改变异常源头
            throw e.fillInStackTrace(); // b:改变异常源头, 通过fillInStatckTrace实现
        }
    }
    
    /**
     * 抛出一个新的异常,改变了异常句柄
     */
    private static void rethrowNew() {
        try {
            f();
        } catch (Exception e) {
            System.out.println("Caught in rethrowNew, e.printStackTrace()");
            e.printStackTrace();
            //throw new NullPointerException("from rethrowNew"); // RuntimeException,编译器自动处理
            try {
                throw new Exception("from rethrowNew"); // 非RuntimeException,必须捕捉
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    /**
     * 运行期异常,勿须捕捉,编译器会自动处理
     */
    private static void f1() {
        throw new RuntimeException("From f1()");
    }

    /**
     * 运行期异常测试
     */
    private static void runtimeExceptionTest() {
        try{
            f1();
        } catch (RuntimeException e){
            e.printStackTrace();
        }
    }
    
    /**
     * Error错误
     */
    private static void error() {
        throw new Error("custome error,not exception. ");
    }
    
    /**
     * Error测试
     */
    private static void errorTest(){
        try{
            error();
        } catch (Error t){ 
            t.printStackTrace();
        }
    }
}

运行结果:

originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
    at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)
    at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:49)
    at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)
Caught exception in reThrowTest, e.printStackTrace()
java.lang.Exception: thrown from f()
    at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:54)
    at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)
originating the exception in f()
Caught in rethrowNew, e.printStackTrace()
java.lang.Exception: thrown from f()
    at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)
    at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:63)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)
java.lang.Exception: from rethrowNew
    at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:69)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)
java.lang.RuntimeException: From f1()
    at com.chq.study.ThrowableExceptionStudy.f1(ThrowableExceptionStudy.java:80)
    at com.chq.study.ThrowableExceptionStudy.runtimeExceptionTest(ThrowableExceptionStudy.java:88)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:16)
java.lang.Error: custome error,not exception. 
    at com.chq.study.ThrowableExceptionStudy.error(ThrowableExceptionStudy.java:98)
    at com.chq.study.ThrowableExceptionStudy.errorTest(ThrowableExceptionStudy.java:106)
    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:17)