异常处理Throwable

1、异常分类

Error错误--程序无法处理的错误,表示运行应用程序中较严重问题(运行时异常:StackOverFlowErrorOutOfMemoryError)这些错误表示故障发生于虚拟机自身或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。

 

Exception异常(重要子类:RunTimeException运行异常、IOException

RunTimeException:例如空值对象引用,试图除零、数组越界则分别引发运行时异常(NullPointerExceptionArithmeticException)和ArrayIndexOutOfBoundException

异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。

Java异常(包括ExceptionError)分为可查异常checked Exceptions)和不可查异常(unchecked Exceptions)

可查异常(编译器要求的必须处置的异常):在一定程度上它的发生是可以预计的,且一旦发生,就必须采取相应程序进行处理。除了RunTimeException及其子类外,其他的Exception都是可查异常,编译器会检查,需要try catchthrows抛出异常,否则编译器不会通过。

不可查异常(编译器不要求强制处置的异常)包括运行时异常(RuntimeException与其子类)和错误(Error

 

运行时异常:RuntimeException类及其子类,这些异常不可查,java编译器不会检查它,无需try catch throws,也会编译通过。

非运行时异常(编译异常):RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常try catch throws,如果不处理,程序就不能编译通过。

2、处理异常机制

抛出异常:当方法出现错误引发异常时,方法创建异常对象(异常对象包含异常类型和异常出现时的程序状态等异常信息)并交付给运行时系统,运行时系统找到处理异常的代码并执行。

捕获异常:在方法抛出异常后,运行时系统会寻找合适的异常处理器(exception handler

潜在的异常处理器是异常发生时存留在调用栈中的方法的集合。当异常处理器所能处理的类型与发生异常的类型相同时,即找到合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈,直到找到合适的异常处理器,如果遍历完仍未找到,则运行时系统停止。

对于所有的可查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉可查异常时,它必须声明将抛出异常。

总结:

能够捕捉异常的方法,需要提供相符类型的异常处理器。所捕捉的异常,可能是由于自身语句所引发并抛出的异常,也可能是由某个调用的方法或者Java运行时 系统等抛出的异常。也就是说,一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的。

 

从方法中抛出的任何异常都必须使用throws子句。

捕捉异常通过try-catch语句或者try-catch-finally语句实现。

总体来说,Java规定:对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeExceptionError

3、捕获异常try catch finally

注意事项:一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch语句结束。其他的catch子句不再有匹配和捕获异常类型的机会。

Java通过异常类描述异常类型,异常类的层次结构如图1所示。对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。

例如:RuntimeException异常类包括运行时各种常见的异常,ArithmeticException类和ArrayIndexOutOfBoundsException类都是它的子类。因此,RuntimeException异常类的catch子句应该放在最后面,否则可能会屏蔽其后的特定异常处理或引起编译错误。

小结:

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。

catch 块:用于处理try捕获到的异常。

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

1)在finally语句块中发生了异常。

2)在前面的代码中用了System.exit()退出程序。

3)程序所在的线程死亡。

4)关闭CPU

trycatchfinally语句块的执行顺序:

1)当try没有捕获到异常时try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

2)try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

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

4、抛出异常:

1、throws抛出异常

当方法可能会出现异常,但没有能力处理这种异常,可以在方法中声明throws抛出异常,例如汽车在运行时可能会出现故障,但汽车本身无法解决,得抛给开车的人。

Throws语句用在方法定义时声明该方法要抛出的异常类型,多个类型用逗号分隔。

methodname throws Exception1,Exception2,..,ExceptionN{  

}

方法名后的throws Exception1,Exception2,..,ExceptionN为异常列表,当方法遇到异常列表中异常及其子类时,将不做处理直接抛给调用该方法的方法。

import java.lang.Exception;  
public class TestException {  
    static void pop() throws NegativeArraySizeException {  
        // 定义方法并抛出NegativeArraySizeException异常  
        int[] arr = new int[-3]; // 创建数组  
    }  
  
    public static void main(String[] args) { // 主方法  
        try { // try语句处理异常信息  
            pop(); // 调用pop()方法  
        } catch (NegativeArraySizeException e) {  
            System.out.println("pop()方法抛出的异常");// 输出异常信息  
        }  
    }  
}

pop方法没有处理异常NegativeArraySizeException,而是由main函数来处理。

throws抛出异常的规则

(1)如果是不可查异常(unchecked exception),即runtimeException或者Error,在编译期间不会对其检查也会通过,无需用throws抛出异常。

(2)如果一个方法中会出现可查异常则必须用try-catch捕获或是throws声明抛出,否则编译会出错。

(3)仅当抛出了异常,该方法的调用者才必须处理或重新抛出异常。

(4)调用方法必须遵循任何可查异常的处理和声明规则。当继承时,若覆盖一个方法,声明的任何异常都必须与重写方法所声明的异常相同或是异常的子类。

2、使用throw抛出异常

throw可以在函数体中使用,并且需要在出现的方法中声明throws 抛出与throw相同的异常。Throw用来抛出一个Throwable的异常,程序会在throw后立即停止,后面的语句执行不到,然后在包含它的try块中(可能在调用函数中)从里向外查找匹配的异常处理catch字句(Java这种向上传递异常信息的处理机制,形成异常链)。

注意:当所有的方法都层层上抛异常,最终会交给JVM处理,打印异常消息和堆栈消息。如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。

package Test;  
import java.lang.Exception;  
public class TestException {  
    static int quotient(int x, int y) throws MyException { // 定义方法抛出异常  
        if (y < 0) { // 判断参数是否小于0  
            throw new MyException("除数不能是负数"); // 异常信息  
        }  
        return x/y; // 返回值  
    }  
    public static void main(String args[]) { // 主方法  
        int  a =3;  
        int  b =0;   
        try { // try语句包含可能发生异常的语句  
            int result = quotient(a, b); // 调用方法quotient()  
        } catch (MyException e) { // 处理自定义异常  
            System.out.println(e.getMessage()); // 输出异常信息  
        } catch (ArithmeticException e) { // 处理ArithmeticException异常  
            System.out.println("除数不能为0"); // 输出提示信息  
        } catch (Exception e) { // 处理其他异常  
            System.out.println("程序发生了其他的异常"); // 输出提示信息  
        }  
    }  
  
}  
class MyException extends Exception { // 创建自定义异常类  
    String message; // 定义String类型变量  
    public MyException(String ErrorMessagr) { // 父类方法  
        message = ErrorMessagr;  
    }  
  
    public String getMessage() { // 覆盖getMessage()方法  
        return message;  
    }  
}

5Throwable类中的常用方法

注意:catch关键字后面括号中的Exception类型的参数e。Exception就是try代码块传递给catch代码块的变量类型,e就是变量名。catch代码块中语句"e.getMessage();"用于输出错误性质。通常异常处理常用3个函数来获取异常的有关信息:

getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。

getMeage():返回异常的消息信息。

printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。

有时为了简单会忽略掉catch语句后的代码,这样try-catch语句就成了一种摆设,一旦程序在运行过程中出现了异常,就会忽略处理异常,而错误发生的原因很难查找。

6Java常见异常

在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:

1. runtimeException子类:

    1、java.lang.ArrayIndexOutOfBoundsException

    数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。

    2、java.lang.ArithmeticException

    算术条件异常。譬如:整数除零等。

    3、java.lang.NullPointerException

    空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等

    4、java.lang.ClassNotFoundException

    找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

   5、java.lang.NegativeArraySizeException  数组长度为负异常

   6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常

   7、java.lang.SecurityException 安全性异常

   8、java.lang.IllegalArgumentException 非法参数异常

2.IOException

IOException:操作输入流和输出流时可能出现的异常。

EOFException   文件已结束异常

FileNotFoundException   文件未找到异常

3.其他

ClassCastException    类型转换异常类

ArrayStoreException  数组中包含不兼容的值抛出的异常

SQLException   操作数据库异常类

NoSuchFieldException   字段未找到异常

NoSuchMethodException   方法未找到抛出的异常

NumberFormatException    字符串转换为数字抛出的异常

StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常

IllegalAccessException  不允许访问某类异常

InstantiationException  当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值