Error 相关类型的异常是程序没法处理(大多都是修改代码没法解决的)的异常,这类异常一般须要咱们调整JVM的运行环境java
Exception 相关类型的异常是程序能够处理的异常,其包含两大子类型code
编译异常(CheckedException)对象
一般是语法错误,或是方法明确指明可能抛出异常则必须捕获处理blog
运行时异常(RuntimeException)继承
指的是检查阶段没有发现任何问题,知足全部语法规范,只有在运行时才能发现的异常编译器
关键字 try catch finally throws throw虚拟机
基本语法:it
注意:io
finally 表示最终,即不管异常是否真的发生了,最终都会执行finally编译
如要打断finally的执行能够直接退出虚拟机,System.exit();
在方法中,若是有finally,即便在 try 或catch中遇到了return 语句,方法也不会当即结束,而是必须执行完finally后才会执行结束,
案例:
class Test{ public static void main(String[] args){ System.out.println(func(0)); //此处获得的结果为10000; //若是没有finally 则是10; } public static int func(int arg){ try{ int a = 1/arg; return a; }catch(Exception e){ return 10; }finally{ return 10000; } } }
用于方法定义,在定义方法时可使用throws来声明,方法可能会抛出某种类型的异常
当方法中可能会有异常,可是方法自己没法处理,或是不想处理....就可使用throws来抛出
须要强调的是:若是一个异常抛出后没最终没有获得处理,将致使程序运行中断,因此一般咱们不能听任无论
注意:
简单的说,只要声明了,则代表方法内部不会处理该异常,谁调用就由谁处理;
一个方法也能够声明抛出多种不一样类型异常,响应的调用方应增长对应的catch
案例:
package com.yh.test; public class Test { public static void main(String[] args){ //一直抛向程序入口都没有获得处理则程序被终止 func3(); } static public void func2() throws ArithmeticException{ int a = 1/0; } static public void func3() throws ArithmeticException{ try{ func2();//func2抛出异常 }catch (Exception e){ //没法处理则继续向上抛出 throw e; } } }
抛出多种类型异常:
import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args){ try { func3(); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch (InputMismatchException e) { e.printStackTrace(); } } static public int func3() throws ArrayIndexOutOfBoundsException,InputMismatchException{// try{ int a = new Scanner(System.in).nextInt(); return 10/a; } }
当方法的提供者须要调用者提供一些数据,可是这些数据不合法,致使功能没法正常处理时,就应该主动抛出异常
调用方能够在捕获到异常后进行处理
方法内部致使的异常本身处理,调用者致使的异常则抛出(或者能处理则处理)
由于Exception 既包含了运行时异常 又包含了 编译时异常,因此要求必须处理,由此可知,当throws声明的异常为编译时异常时则要求必须提供处理代码;
案例:
package com.yh.test; public class Test { public static void main(String[] args){ try { func(1); } catch (Exception e) { e.printStackTrace(); } } static void func(int a) throws Exception{ if (a < 1){ throw new Exception("参数不能小于1"); } } }
当内置异常没法知足特色业务场景时,能够自定义异常类,只须要继承Exception便可
案例:
class MyException extends Exception{ public MyException() { super("固定的异常提示!"); } }
当异常提示信息固定的时候能够像上面同样定义构造器
当一个方法抛出的异常被调用方法捕获,可是调用方法又抛出了新的异常时,则造成了异常链,
若是咱们在调用方法中直接抛出新的异常不作任何额外的操做时,原始异常信息则被丢失;
咱们有两个方法能够保留原始异常信息
1.实例化时使用原始异常做为参数
2.实例化后调用initCause传入原始异常对象
案例:
package com.yh.test; public class ExceptionLinkeTest { public static void main(String[] args) { try { func2(); } catch (Exception e) { e.printStackTrace(); } } static public void fun1() throws ArithmeticException{ int a = 1 / 0; } static public void func2() throws Exception{ try{ fun1(); }catch (ArithmeticException e){ //不保留原始异常信息 //throw new Exception("新的异常信息!"); //保留异常信息方法1 throw new Exception("新的异常信息!",e); //保留异常信息方法2 Exception newex = new Exception("新的异常信息!"); newex.initCause(e); throw newex; } } }
当咱们不作处理时,获得的异常信息以下:
使用 方法1或方法2 来保留异常信息结果以下: