异常及其处理办法

第一章 异常

异常:指的是程序执行中,出现非正常的情况,最终导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身就是一个类,产生异常其实就是创建异常对象,并且抛出一个异常对象,java处理异常的方式是中断处理。

异常指的并不是语法错误,语法错误编译不会通过,不会产生字节码文件(class文件),根本不能运行 。

1.2异常体系

异常机制就是帮助我们找到程序中的问题,异常的根类是。

java.lang.Throwable,其下有两个子类:java.lang.Error与java.lang.Exception ,平时我们常说的异常是Exception。

  • Error:严重的错误,无法通过处理的错误,只能事先避免,就像绝症。

  • Exception:表示异常,异常产生后程序员可以通过代码修正,让程序继续运行,是必须要处理的。就像普通感冒等。

Throwable中常用的方法

  • public void printStackTrace():打印异常的详细信息。

    • 包含了异常的类型,异常的原因,异常出现的位置,在开发和调试中都需要使用。

  • public String getMessage(): 获取异常发生的原因。

    • 提示给用户,只提示错误原因。

  • public String toString(); 获取异常的类型和异常的描述信息(基本不用)。

出现异常,不要紧张,把异常的简单类名,拷贝出去搜索

1.3异常分类

异常的分类:根据编译期异还是运行期去检查异常?

  • 编译期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。

  • 运行期异常:runtime异常。在运行时期,检查异常,在编译时期,运行异常不会编译器检测(不报错)。

第二章 异常的处理

Java异常处理的五个关键字: try、catch、finally、throw 、thorws

2.1抛出异常throw

编写方法时,如果方法需要接受参数,那么当调用方法时传入的参数的合法性就需要判断,数据如果不合法 就该通知调用者,传递合法的参数,这时需要使用抛出异常的方式来告诉调用者。

在java中,提供throw关键字,也用来抛出一个指定的异常对象。

使用步骤:

1.创建一个异常对象。封装一些提示信息(信息可以自己编写)。

2.需要将这个这个异常对象抛出给调用者 ,throw异常对象。

throw用在方法内,用来抛出异常对象,将这个异常传递给调用者,并结束当前方法的执行。

public class Demo01 {
    public static void main(String[] args) {
        //创建一个数组
        int[] arr = {12, 2, 3, 4, 1};
        //根据索引找对应元素
        int index = 444444;
        int element = getElement(arr, index);
        System.out.println(element);
        System.out.println("over");
    }
    public static int getElement(int[] arr, int index) {
        //判断 索引是否越界
        if (index < 0 || index > arr.length - 1) {
            throw new ArrayIndexOutOfBoundsException("兄弟,越界了");
        }
        int element = arr[index];
        return element;
    }
}

2.2Objects非空判断

public class Demo02 {
    public static void main(String[] args) {
        Demo01 demo01 =new Demo01();
        demo01=null;
        Demo01 demo02 = Objects.requireNonNull(demo01);
        System.out.println("demo02 = " + demo02);
    }
}

2.3声明异常throws

声明异常:将问题标识出来,报告给调用者,

如果方法内通过throw抛出了异常,而没有进行捕获处理,那么必须通过throws进行声明,让调用者处理。

关键字throws运用于方法声明之上,用于标识当前方法不处理异常,而是提示该方法的调用者来处理异常(抛出异常)。

异常关键字概要
    throw抛出异常  写在方法中    后面抛出的是一个异常对象。
   throws声明异常(不代表这个类中一定会发生这种异常,一般只用在声明编译期异常) ,写在方法上     后面跟的是异常类名。
public class Demo03 {
  
    public static void main(String[] args) throws FileNotFoundException,IOException {
        read("aa.txt");
    }
    public static  void read(String path) throws FileNotFoundException ,IOException {
        //假设 如果传入的地址 不是a.txt  就认为该文件不存在 是一个异常
        if (!path.equals("a.txt")){
            throw new FileNotFoundException("文件不存在");
        }
        if (!path.equals("b.txt")){
            throw new IOException();
        }
        System.out.println("11111");
    }

}

2.4捕获异常try..catch

如果异常出现的话 我们必须处理异常:

在方法中使用try-catch的语句块来处理异常。

  • 捕获异常: Java中对异常有针对性的语句进行捕获,可以对出现异常进行指定方式的处理。

格式:

try{
    编写可能会出现异常的代码。
}catch(异常类型  e){
    用来进行某种异常的捕获,实现对捕获到的异常进行处理。
        // 记录日志/打印异常信息/继续抛出异常。
}

当产生异常时,必须有处理方式,要么捕获 要么声明

public class Demo04 {
    public static void main(String[] args) {
        try {
            //当产生异常时,必须有处理方式,要么捕获 要么声明。
            read("a.txt");
        } catch (FileNotFoundException e) {//括号里面需要定义异常  但是具体定义什么异常呢?
//            try中抛出的是什么异常   括号中就定义什么异常。
            e.printStackTrace();
        }catch (Exception e ){
            System.out.println(e.toString());
            System.out.println("22222222");
        }
        System.out.println("over");
    }

    public static void read(String path) throws FileNotFoundException, IOException {
        //假设 如果传入的地址 不是a.txt  就认为该文件不存在 是一个异常
        if (!path.equals("a.txt")) {
            throw new FileNotFoundException("给用户看的报错信息");
        }
        if (!path.equals("b.txt")) {
            throw new IOException();
        }
        System.out.println("11111");
    }
}
public class Demo05 {
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(1);
        try {
            System.out.println(1 / 0);
        }catch (Exception e){//捕获异常了,执行该括号中的问题
            e.printStackTrace();
            System.out.println("我遇到了异常");
        }
        System.out.println(1);
        System.out.println(1);
        System.out.println(1);
    }
}

2.5 finally 代码块

finally: 有一些特定的代码 无论异常是否发生,都需要执行。另外,异常会引发程序跳转,导致某些语句不能执行,finally主要就是为了解决这个问题,finally中的代码一定会被执行。

什么样的代码必须要最终执行?

当我们在try中打开了一些物理资源(磁盘文件/网络链接/数据库链接等),我们都需要在使用完资源,关闭打开的资源。

finally语法:

try...catch ..finally :注意: finally不能单独使用。

比如之后学习的io流中,当打开了一个关联文件的资源,最后程序不管结果如何 ,都需要关闭这个资源。

除非是  System.exit(1);   如果调用退出jvm的相关方法 ,此时finally才不会执行,否则finally永远执行。

finally代码示例:

public class Demo06 {
    public static void main(String[] args) {
        try{
            read("aa.txt");
        }catch (FileNotFoundException e){
            throw new RuntimeException("这里把编译期异常,转化为运行期异常");
        }finally{
            System.out.println("不管发生什么 我都会执行");
        }
        System.out.println("over");

    }
    private static void read(String path) throws FileNotFoundException {
         if (!path.equals("a.txt")){
             throw new FileNotFoundException("文件不存在");
         }
    }
}

2.6异常注意事项

  • 运行时异常被抛出 可以不处理。即不捕获也不声明抛出。

  • 如果父类抛出了多个异常,子类覆盖父类方法 ,只能抛出相同的异常。

  • 父类方法没有抛出异常,子类重写父类方法时也没有抛出异常。此时子类产生异常,只能捕获处理,不能抛出。

  • 当处理多个异常,捕获处理时,前面的异常类 不能是后面类的父类。

  • try catch后面追加finally时,其中代码一定会被执行,通常用于资源关闭。

  • 多个异常如何处理?

    • 1.多个异常分别处理。(常用)

    • 2.一次捕获 多次处理。

    • 3.一次捕获一次处理。(常用)

第三章 自定义异常

3.1 概述

为什么需要自定义异常:

很多异常没有在jdk中定义过,例如年龄负数,成绩负数,等问题。

什么是自定义异常?

在开发中根据自己实际业务定义的异常类。

例如:我们自定义一个业务逻辑异常:LoginException。一个登录异常类;

异常类如何自定义

1.自定义一个编译期异常:自定义类 继承Exception

2.自定义一个运行期异常: 自定义类 继承RunTimeException

public class LoginException extends Exception {

    public LoginException(){
    }
    /**
     * @param message   表示异常的提示
     */
    public LoginException(String message){
        super(message);
        System.out.println("创建了异常对象");
    }

}
public class Demo09 {

    //    模拟数据库中已经存在的账号
    private static String[] names = {"aaa", "bbb", "ccc"};
    public static void main(String[] args) {
        try {
            checkUserName("aaa");//可能出现异常的代码
            System.out.println("注册成功");
        } catch (LoginException e) {
            e.printStackTrace();
        }
    }
    //方法 判断当前账号是否存在 如果不存在 抛出异常  LoginException是编译期异常, 又想调用者处理 所以声明异常
    public static boolean checkUserName(String name) throws LoginException {
        for (int i = 0; i < names.length; i++) {
            if (names[i].equals(name)) {
                throw new LoginException("亲," + name + "已经被注册了");
            }
        }
        return true;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值