Java中的异常处理机制

Java中的异常处理机制

1.异常:导致程序无法正常运行的Exception或者Error;例如:文件找不到、数组下标越界、非法参数、网络连接失败等。

2.Java异常层次结构图
这里写图片描述

在Java中Throwable是所有异常的超类,它有两个重要的子类:Error和Exception;Throwable中常用的方法:

getCause():返回抛出异常的原因
getMessage:返回异常的消息信息
printStackTrace():把Throwable对象的堆栈跟踪输出到错误输出流

Error:表示程序无法处理的错误,一般是由Java虚拟机引起,理论上程序中不允许这些错误的发生,如果出现也不应通过程序去处理;也可以大概分为两部分:VirtulMachineError(虚拟机错误)和AWTError(AWT组件错误);

1.VirtulMachineError—–虚拟机错误:

在Java运行时内存中,除程序计数器外的虚拟机栈、堆、方法区在请求的内存无法被满足时都会抛出OutOfMemoryError;
而如果线程请求的栈深度超出虚拟机允许的深度时,就会抛出StackOverFlowError;、

2.AWTError—–AWT组件错误:这个错误一般不常见就不做深入介绍,解释一下AWT和Swing组件的区别:

AWT是使用操作系统中的图形函数的抽象窗口工具,用C\C++编写,为了实现Java“一次编译,处处运行”的理念,AWT使用各个操作系统图形函数的交集,所以功能较差,但运行速度较快,适合嵌入式Java;
而Swing组件是基于AWT编写的图形界面系统,它用纯Java编写,所以必然实现了“一次编译,处处运行”,但相较于AWT运行速度较慢,适合PC使用。

Exception:这种类型异常的出现一般是由于我们的程序本身的问题引起的,我们也应当在程序中去处理掉这些异常;异常也分为 两类:可查异常和不可查异常

可查异常(也称非运行时异常):指在编译期就必须处理的异常,否则程序无法正常编译,可以通过try-catch捕捉或者throw/throws抛出;

部分可查异常有如下一些类别:
这里写图片描述

不可查异常(也称运行时异常):指在编译期可以不处理,一旦这种异常出现,一般是Java虚拟机接管;

部分常见的运行时异常:
这里写图片描述

3.异常处理机制

异常的处理有两种方式:

1.抛出异常(throw/throws)
2.直接捕获(try·····catch)

抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

1.通过throws抛出异常
throws是添加在方法上抛出的异常,可以同时抛出多种异常,多种异常分别用逗号分隔;

throws抛出异常的规则:
1) 如果是不可查异常,即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。

2)必须声明方法可抛出的任何可查异常。即如果一个方法可能出现可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误

3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续向上抛出。

4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类

2.通过throw抛出异常
throw是在方法体内抛出异常的方法,而且通常都是在try/catch语句块中抛出,throw抛出的是异常的对象,一般要在方法调用的上一级通过try····catch捕捉遗产;

public class Demo2 {

    public static void main(String[] args) {

        /*
         * 如果这里不通过try/catch捕获异常,则异常会交付给运行时系统处理即也会直接报错
         */
        try {
            Demo2.test();
        } catch (Exception e) {
            System.out.println("到这啦!");
        }
    }

    @SuppressWarnings("null")
    public static void test(){

        String str=null;
        try {
            str.equals("");

            //如果上一句出现异常,则下面的都不会在运行
            System.out.println("111");

        } catch (Exception e) {

            /*
             * 在这里抛出一个异常对象
             */
            throw new RuntimeException("这里有问题!");
        }
    }
}

捕获异常:针对出现的异常情况我们自己直接进行处理,而不是由虚拟机报错,一般是由try/catch/finally语句块进行处理;

1.try:其中可能会发生异常的程序段

2.catch:对应的异常处理器方法,当抛出异常后,由运行时系统在栈中从当前位置开始依次回查方法,直到找到合适的异常处理方法,如果未找到,则执行finally或直接结束程序运行。

3.finally:无论是否捕获或处理异常,finally块里的语句都会被执行。 注意(很重要,面试常问):当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
在以下4种特殊情况下,finally块不会被执行:

1)在finally语句块中抛出了异常且未处理。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。

注意:try/catch/finally语句块中catch和finally中可以同时存在,也可以只出现一个,但必须要有其中一个的存在

try/catch/finally语句块的执行顺序:

1.当没有捕获到异常时,直接跳过catch语句块,运行finally语句块中的代码

public class TestException {
    public static void main(String[] args){         

        try {
            System.out.println("Hello world!");
        } catch (NullPointerException e) {
            System.out.println("Catch NullPointerException!");
        }catch (ArithmeticException e) {
            System.out.println("Catch ArithmeticException!");
        }catch(Exception e){
            System.out.println("Catch other Exception!");
        }
        finally{
            System.out.println("Finally!");
        }   
    }
}
/*
  输出结果:
  Hello world!
  Finally!
 */

2.当抛出运行时异常且没有定义相应的异常处理方法,就会由JVM抛出异常。

public class TestException {
    public static void main(String[] args){         
        String str = null;  
        int a = 2, b = 0;
        //调用空对象的方法,会抛出空指针异常
        System.out.println(str.length());       
    }
}
/*
 输出结果:
 Exception in thread “main”java.lang.NullPointerException 
 at Java面试.TestException.main(TestException.java:11)
 */

3.当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,最后执行finally语句块后的语句。

public class TestException {
    public static void main(String[] args){         
        String str = null;  
        int a = 2, b = 0;
        try {
            //调用空对象的方法,会抛出空指针异常
            System.out.println(str.length());  //语句1

            //除数为0,会抛出数学运算错误,因为上一句出了异常所以下面的语句都不会再运行
            System.out.println("a/b=" + a/b);  //语句2
        } catch (NullPointerException e) {
            System.out.println("Catch NullPointerException!");

        }catch (ArithmeticException e) {
            System.out.println("Catch ArithmeticException!");

        }catch(Exception e){
            System.out.println("Catch other Exception!");
        }
        finally{
            System.out.println("Finally!");
        }   
    }
}

/*
 输出结果:
 Catch NullPointerException! 
 Finally!
*/

Java异常处理的原则:必须声明抛出异常或捕获可查异常,允许忽略Error与不可查异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值