Java异常

异常就是在程序的运行过程中所发生的意外事件,它中断指令的正常执行。可能导致程序发生非正常情况的原因有很多,如数组下标越界、算术运算被0除、空指针访问、试图访问不存在的文件等。

异常的类层次(常见)

java异常分级 java异常级别_抛出异常

java异常分级 java异常级别_java异常分级_02

Java 异常处理机制:

Error: 错误 Error 类指的是系统错误或运行环境出现的错误,这些错误一般是很严重的错误,即使捕捉 到也无法处理,由 Java 虚拟机生成并抛出,包括系统崩溃、动态 链接失败、虚拟机错误等,在 Java 程序中 不做处理。

Exception: 异常 Exception 类则是指一些可以被捕获且可能恢复的异常情况,是一 般程序中可预知的问 题。对于异常可分为两类:

  • (1) 运行时异常:由系统检测, 用户的 Java 程序中可以不做处理,系统将它们交给 缺省的异常处理程序,例如:
public class TestDemo{
    public static void main(String[] args) {
        int[] arr = new int[10];
        arr[10] = 100;
        System.out.println(arr[10]);
    }
}

编译期间不报错,运行期间异常(下标越界)

java异常分级 java异常级别_Java_03

  • (2) 非运行时异常:在程序中必须对其进行处理,否则编译器会指出错误。

java异常分级 java异常级别_抛出异常_04

编译时报错,需要进行异常处理

java异常分级 java异常级别_System_05

异常的处理结构
  • Java 异常处理通过 5 个关键字 try,catch,finally,throw 和 throws 进行管理
  • Java 中处理异常有两种方式:捕获异常、声明抛出异常。
    捕获异常:就地解决,并使程序继续执行。
    声明抛出异常:就是将异常向外转移,即将异常抛出方法之外,由调用该方法的环境去处理。
捕获异常

try: 捕获异常的第一步是用 try{…}选定捕获异常的范围,try 模块中的语句是程序正常流程要执行的语句,但 是在执行过程中有可能出现异常。所有可能抛出异常的语句都放入 try 模块中。

catch(必有): 每个 try 代码块可以伴随一个或多个 catch 语句,用于处理 try 代码块中所生成的异常事件。catch 语句只 需要一个形式参数指明它所能够捕获的异常类型,这个类必须是 Throwable 的子类,运行时系统通过参数值把被 抛弃的异常对象传递给 catch 块。在 catch 块中是对异常对象进行处理的代码,与访问其它对象一样,可以访问一个异常对象的数据成员或调用它的方法。

  • getMessage()是类 Throwable 所提供的方法,用来得到有关异常事件的信息,
  • 类 Throwable 还提供了方法 printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。

catch 语句的顺序: 捕获异常的顺序和 catch 语句的顺序有关,当捕获到一个异常时,剩下的 catch 语句就 不再进行匹配。因此, 在安排 catch 语句的顺序时,首先应该捕获最特殊的异常,然后 再逐渐一般化。也就是一般先安排子类,再安排父类。

finally(可选) : 捕获异常的最后一步是通过 finally 语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分 以前,能够对程序的状态作统一的管理。不论在 try 代码块中是否发生了异常事件,finally 块中的语句都会被执行。

try{
  语句块;
}
catch(异常类名   参变量名)  {  语句块;  }
finally  {  语句块;  }
抛出异常

在 Java 程序的执行过程中,如果出现了异常事件,就会生成一个异常对象。生成的异常对象将传递给 Java 运 行时系统,这一异常的产生和提交过程称为抛出(throw)异常。

声明抛出异常

(1) 一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明抛出异常(throws)。声明抛出异常是一种消极的异常处理机制。

(2) 抛出异常就是产生异常对象的过程,首先要生成异常对象,异常或者由虚拟机生成,或者由某些类的实例 生成,也可以在程序中生成。在方法中,抛出异常对象是通过 throw 语句实现的。

注意:

IOException  e = new IOException();
 throw e;
  • 可以抛出的异常必须是 Throwable 或其子类的实例。
  • throws 子句中同时可以指明多个异常,之间由逗号隔开。
  • 对 Error 类或其子类的对象,程序中不必进行处理。
  • 对 RuntimeException 类或其子类,程序中可以不必进行处理。
  • 除此之外的异常,程序员都应该在程序中进行处理。

处理方式分为以下几种:

① 要么用 try-catch-finally 进行捕获处理

② 要么明确表示不处理从而声明抛出异常

③ 要么先捕获处理然后再次抛出。

在进行异常处理过程中应该注意:

Java 的异常处理机制(try-catch-finally 语句、throws 子句、throw 语句)会带来 Java 程序代码结构上的改变。

① 不能滥用异常机制。简单的出错判断建议用 if 语句。

② 不要过分细分异常。

自定义异常
1、自定义异常类设计

在程序中,可以创建自定义的异常类。用户定义的异常必须继承自 Throwable 或 Exception 类,建议用 Exception 类。

2、抛出异常

例如:

//自定义异常类
class MyException extends Exception{
    String id;//异常标识
    public MyException(String str){
        id=str;
    }
    public String toString(){
        return ("异常:"+id);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        try{
            throw new MyException("一个测试异常!");
        }catch(MyException e){
            System.out.println(e);
        }
    }
}

结果:

java异常分级 java异常级别_System_06

3、方法的异常声明
修饰符   返回类型   方法名(参数列表) throws  异常类名列表{
 ...
 throw  异常类名;
 ...
}

总结

异常处理(一般只针对编译期异常) -> 五个关键字(try catch finally throw throws)

一个try块对应一个或者多个catch块

1、try:

注意:

  • 1)如果当前try块中存在多条可能会发生异常的代码A,B C 三条语句,如果A发生异常,此时B,C语句不会被执行到。
  • 2)try块尽量避免嵌套
public class TestDemo{
    public static void main(String[] args) {
         //只关心ClassNotFoundException
        int[] arr = {0};
        //可能发生异常的代码
        try {
            arr[1] = 10;//JVM抛出异常对象
            Thread.sleep(1000);
            //return之前调用finally
//            return;
            System.exit(0);
        }catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {//特点是:无论是否发生异常必定会被执行到
            System.out.println("finally");
            System.exit(0);
//            return;
        }
    }
}

2、catch -> 尽量避免过细划分异常

注意:

catch(NullPointerException){  //先用关心的子类处理,不关心的直接用父类处理

}catch(Exception e){

}

3. finally: 特点是:无论是否发生异常必定会被执行到

TODO: 1) final finally finalize

TODO:2)如果try块里面包含 return;并且finally块也包含return;
       	从finally块return退出
       	
TODO: 3) 如果try块里面含有退出System.exit();finally也包含:问:此时从哪里退出
        从try块中System.exit退出

4、throw:

扔异常对象

例如:throw new EmptyStackException();

class MyStack{
    private int[] element;
    private int size;
    public static final int CAPACITY  = 10;
    public MyStack(){
        this(CAPACITY);
    }
    public MyStack(int num){
        element = new int[num];
    }
    public int peek(){
        if(size == 0){//EmptyStackException
            throw new EmptyStackException();
        }
        return element[size-1];
    }
}

5、throws

void fun()throws InterruptedException{
	Thread.sleep(1000);//(单位毫秒)
}
//调用处:
try{
	fun();//谁调谁处理
}catch(InterruptedException e){
	e.printStackTrace();
}