Java 复习笔记5 - 异常处理

异常处理

异常分类与体系结构:

image-20191121094447105

Error 相关类型的异常是程序没法处理(大多都是修改代码没法解决的)的异常,这类异常一般须要咱们调整JVM的运行环境java

Exception 相关类型的异常是程序能够处理的异常,其包含两大子类型code

  • 编译异常(CheckedException)对象

    一般是语法错误,或是方法明确指明可能抛出异常则必须捕获处理blog

  • 运行时异常(RuntimeException)继承

    指的是检查阶段没有发现任何问题,知足全部语法规范,只有在运行时才能发现的异常编译器

异常处理

关键字 try catch finally throws throw虚拟机

基本语法:it

image-20191121100239487

注意:io

  • try 没法单独使用,必须与catch 或finally 组合使用
  • finally 表示最终,即不管异常是否真的发生了,最终都会执行finally编译

  • 当异常类型为Exception时 表示通用异常处理(万能异常处理),能够捕获全部异常可是没法针对性的处理
  • 一个try能够有多个catch
  • 一般将Exception添加到最后一个catch中做为彻底保证,让程序能够继续运行
  • 一个try中的全部catch下每一个异常类型只能出现一次
  • catch中异常类型必须从小到大(先子类在父类)
  • 不管有多个catch最终只有一个会被执行(相似 if else.....)
  • 如要打断finally的执行能够直接退出虚拟机,System.exit();

finally 对return的影响

在方法中,若是有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;
    }
  }
}
强调:方法中不管是否出现异常,返回值都以finally中的返回值为准,这是不符合实际的,因此一般不这么写

抛出异常

throws

用于方法定义,在定义方法时可使用throws来声明,方法可能会抛出某种类型的异常

image-20191121103939422

何时使用throws

当方法中可能会有异常,可是方法自己没法处理,或是不想处理....就可使用throws来抛出

须要强调的是:若是一个异常抛出后没最终没有获得处理,将致使程序运行中断,因此一般咱们不能听任无论

使用

image-20191121104306085

注意:

  • 简单的说,只要声明了,则代表方法内部不会处理该异常,谁调用就由谁处理;

  • 相应的调用者则须要捕获异常并处理,若调用方也没法处理,则能够继续向上抛出
  • 一个方法也能够声明抛出多种不一样类型异常,响应的调用方应增长对应的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;
    }
}

throw

主动抛出异常

image-20191121110702483

使用场景:

当方法的提供者须要调用者提供一些数据,可是这些数据不合法,致使功能没法正常处理时,就应该主动抛出异常

调用方能够在捕获到异常后进行处理

抛出仍是处理?

方法内部致使的异常本身处理,调用者致使的异常则抛出(或者能处理则处理)

疑惑:为何throws Exception时编译器要求必须提供解决方案?

由于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;          
        }
    }
}

当咱们不作处理时,获得的异常信息以下:

image-20191121115914351

使用 方法1或方法2 来保留异常信息结果以下:

image-20191121120017971

相关文章
相关标签/搜索