1 Star 0 Fork 0

王浩天 / MyNote

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
异常处理.md 9.08 KB
一键复制 编辑 原始数据 按行查看 历史
王浩天 提交于 2021-10-09 17:38 . 更新异常处理

异常处理

一、异常

​ 异常:就是不正常,是指程序在运行时出现的不正常情况。其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这些信息进行封装。异常就是Java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。

​ 出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这些问题都有共性内容比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位置,所以可以不断的向上抽取。形成了异常体系。

异常的体系:

  • Error:

    通常指JVM出现重大问题如:运行的类不存在或者内存溢出等。

    不需要编写针对代码对其处理,程序无法处理。

  • Exception

    在运行时运行出现的一些情况,可以通过 try,catch,finally 处理。

异常处理两种方式:

  1. 捕获异常:try catch 直接处理可能出现的异常!
  2. 声明异常:throws 声明告诉调用者可能的异常,暴露问题,调用者自己处理!

总结:

​ Exception 和 Error 的子类名大都是以父类名作为后缀。

​ Java 异常其实是对不正常情况的一种描述,并将其封装成对象。

​ Java 在 设计异常体系时,将容易出现的异常情况都封装成了对象。

二、异常处理格式

异常处理的5个关键字:try catch finally throw throws

小总结:

​ 先捕获小异常再捕获大异常。

​ 程序是调出来的,不是写出来的;多测试是程序员的必修课。

​ 异常处理后,程序不会因为出现异常而退出。

异常处理格式

try{
    //可能出现异常的代码
}catch(异常类 对象){
    //处理该异常类型的语句
}
[finally]{
    //一定会执行的代码
    //catch块使用 System.exit(1) 除外
}

​ 备注:当try语句块出现异常,程序会自动跳到catch语句块去找匹配的异常类型,并执行异常处理语句,finally语句块是异常的统一出口。

三、多异常处理

​ 声明异常时尽可能声明具体异常类型,方便更好的处理; ​ 方法声明几个异常就对应有几个 catch 块; ​ 若多个 catch 块中的异常出现继承关系,父类异常 catch 块放在最后; ​ 在 catch 语句块使用 Exception 类作为异常类型时: ​ 所有子类实例都可以使用父类接收(向上转型),即所有的异常对象都可以使用 Exception接收; ​ 注:在java处理多异常时捕获小范围的异常必须放在大范围异常之前。

java 7 - 同时捕获多个异常类型

java 7之前:

try {
	int a = Integer.parseInt("1");
	int b = Integer.parseInt("0");
	int c = a / b;
	System.out.println(c);
} catch (NumberFormatException e){
	e.printStackTrace();
} catch(ArithmeticException e){
	e.printStackTrace();
}

java 7:将多个异常写到了同一个catch代码块

try {
	Integer a = Integer.parseInt("1");
	Integer b = Integer.parseInt("0");
	Integer c = a / b;
	System.out.println(c);
} catch (NumberFormatException | ArithmeticException e ) {
	e.printStackTrace();
}

四、异常的分类

异常分类:

​ Java 语言规范将派生于Error类或RuntimeException类的所有异常称为非受查(unchecked)异常,所有其他的异常称为受查(checked)异常。

  • 编译时被检查的异常——Checked异常

    在程序中必须使用try...catch处理。

  • 编译时不被检查的异常——Runtime异常

    可以不使用try...catch处理,但一旦出现异常就将由JVM处理。

    Java中的异常层次结构如下图:

classDiagram
	Throwable <|--Error
	Throwable <|--Exception
	Exception <|--IOException
	Exception <|--RuntimeException

Runtime异常

RuntimeException(运行时异常)是指因设计或实现方式不当而导致的问题。说白了,就是程序员造成的,程序员小心谨慎是完全可以避免的异常。比如,事先判断对象是否为 null 就 可 以 避 免 NullPointerException 异 常 ,事 先 检 查 除 数 不 为 0 就 可 以 避 免ArithmeticException 异常。

特点:

​ 这种异常Java编译器不会检查它,也就说程序中出现这类异常的时候,即使不处理也没有问题,但是一旦出现异常,程序将异常终止,若采用异常处理,则会被相应的程序执行处理。

派生于 RuntimeException 的异常包含下面几种情况:

  • 错误的类型转换
  • 数组访问越界
  • 访问null指针

​ “ 如果出现 RuntimeException 异常, 那么就一定是你的问题” 是一条相当有道理的规则。应该通过检测数组下标是否越界来避免 ArraylndexOutOfBoundsException 异常;应该通过在使用变量之前检测是否为 null 来杜绝 NullPointerException 异常的发生。

Checked异常

​ 除了 RuntimeException 以及子类,其他的 Exception 及其子类都是受检查异常,我们也可以称为非 RuntimeException 异常.

特点:

​ Java 编译器会检查它,也就说程序中一旦出现这类异常,要么是没有 try-catch 语句捕获,或 throws 语句没有声明抛出它,编译就不会通过,也就说这种异常,程序要求必须处理。

不是派生于 RuntimeException 的异常包括:

  • 试图在文件尾部后面读取数据
  • 试图打开一个不存在的文件
  • 试图根据给定的字符串查找 Class 对象,而这个字符串表示的类并不存在

五、声明异常(throws)

​ 在可能出现异常的方法上声明抛出可能出现异常的类型:

​ 声明的时候尽可能声明具体的异常,方便更好的处理。 ​ 当前方法不知道如何处理这种异常,可将该异常交给上一级调用者来处理(RuntimeException 类型的异常)。

​ 方法一旦使用了throws声明抛出方法内可能出现的异常类型,该方法就可以不再过问该异了; ​ 一个方法调用另一个使用throws声明抛出的方法,自己要么 try...catch,要么也 throws。

格式:

public 返回值类型 方法名(参数列表...) throws 异常A,异常B...{
    //方法体
}

六、throw

​ 自己抛出一个异常对象,抛出异常类的对象;

  • 若 throw 抛出的是 Runtime 异常: 程序可以显式使用 try...catch 来捕获并处理,也可以不管,直接交给方法调用者处理;

  • 若 throw 抛出 Checked 异常: 要么放在try里自己处理,要么放在一个 throws 声明的方法里面,交给调用者处理。

Eg:

public static void main(String[] args) {
	try {
		fn1(1);
	} catch (Exception e) { e.printStackTrace(); }
	fn2(2);
}
public static void fn1(int a) throws Exception{
	if(a >0) { throw new Exception("fn1 -- a 值不合法"); }
}
public static void fn2(int a) {
	if(a >0) { throw new RuntimeException("a 值不合法"); }
}

throws & throw

​ throws 用于在方法上声明该方法不需要处理的异常类型。 ​ throw 用于抛出具体异常类的对象。

throws与throw的区别:

​ throws 用在方法上,后面跟异常类名,可以是多个异常类。 ​ throw 用在方法内,后面跟异常对象,只能是一个。

七、finally

异常的统一出口: 不管 try 块程序是否异常,也不管哪个 catch 执行,finally 块总会执行。 try 语句块或会执行的 catch 语句块使用了 JVM 系统退出语句例外;//System.exit(1); try 块必须和 catch 块或和finally 同在,不能单独存在,二者必须出现一个。 不要在 finally 中使用 return 或 throw 语句,否则将会导致 try、catch 中的 return 或 throw 失效。

Eg:

public class Demo3 {
    public static void main(String[] args) {
        try{
            System.out.println(17/0);
        }catch(Exception e){
            //e.printStackTrace
            System.out.println("错误程序,请修正!");
        }finally{
            System.println("这是finally代码块!");
        }
    }
}

输出: 程序错误,请修正! 这是finally代码块!

八、throw和catch同时使用

​ 当异常出现在当前方法中,程序只对异常进行部分处理,还有一些处理需要在方法的调用者中才能处理完成,此时还应该再次抛出异常,这样就可以让方法的调用者也能捕获到异常。

Eg:

public static void buy(String price) throws Exception{
    try{
        if(price != null)
            Double.parseDouble(price);
    }catch(Exception e){
        e.printStackTrace();
        throw new Exception("价格不能只能是数字组成");
    }
}
public static void main(String[] args){
    try{
        buy(null);
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
}

参考:

  1. 黑马程序员入学Java精华总结
  2. Java核心技术 卷1 基础知识 原书第10版
1
https://gitee.com/wanghaotian123/my-no.git
git@gitee.com:wanghaotian123/my-no.git
wanghaotian123
my-no
MyNote
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891