Java Finally代码块,多异常的捕获处理,finally里面有return,子父类异常,自定义异常类以及小练习。

1、Finally代码块

finally代码块
格式:
try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常对象) {
异常的处理逻辑,产生异常对象之后,怎么处理异常对象
一般在工作中,会把异常的信息记录到一个日志中
}

catch(异常类名 变量名){
}finally{
无论是否出现异常都会执行
}
注意:
1、finally不能单独使用,必须和try一起使用
2、finally一般用于资源释放(资源回收),无论程序是否出现异常,最后都要资源释放
代码演示:

import java.io.IOException;

/*
    finally代码块
    格式:
        try{
            可能产生异常的代码
        }catch(定义一个异常的变量,用来接收try中抛出的异常对象) {
            异常的处理逻辑,产生异常对象之后,怎么处理异常对象
            一般在工作中,会把异常的信息记录到一个日志中
        }
        ...
        catch(异常类名 变量名){
        }finally{
            无论是否出现异常都会执行
        }
    注意:
        1、finally不能单独使用,必须和try一起使用
        2、finally一般用于资源释放(资源回收),无论程序是否出现异常,最后都要资源释放
 */
public class Demo01Finally {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            //可能会产生异常的代码
            readFile("c:\\\\a.tt");
        } catch (IOException e) {
    
    
            //异常的处理逻辑
            e.printStackTrace();
            //java.io.IOException: 文件的后缀名错误
            //at com.itheima.demo02.Demo01Finally.readFile(Demo01Finally.java:39)
            //at com.itheima.demo02.Demo01Finally.main(Demo01Finally.java:27)
        } finally {
    
    
            System.out.println("资源释放"); //资源释放
        }
    }

    public static void readFile(String fileName) throws IOException {
    
    

        if (!fileName.endsWith(".txt")) {
    
    
            throw new IOException("文件的后缀名错误");
        }
        System.out.println("路径无问题,读取文件");
    }
}

2、异常注意事项——多异常的捕获处理

代码演示:

public class Demo02Exception {
    
    
    public static void main(String[] args) {
    
    
        /*
            多个异常使用捕获又该如何处理:

            1、多个异常分别处理
            2、多个异常一次捕获,多次处理
            2、多个异常一次捕获,一次处理
         */

        //1、多个异常分别处理
//        try {
    
    
//            int[] arr = {1, 2, 3};
//            System.out.println(arr[3]);
//        } catch (ArrayIndexOutOfBoundsException e) {
    
    
//            System.out.println(e);
//        }
//
//        try {
    
    
//            List<Integer> list = Arrays.asList(1, 2, 4);
//            System.out.println(list.get(3));
//        } catch(ArrayIndexOutOfBoundsException e){
    
    
//            System.out.println(e);
//        }
//
//        System.out.println("后续代码");
//        int[] arr = {1, 2, 3};
//        System.out.println(arr[3]); //ArrayIndexOutOfBoundsException: 3
//
//        List<Integer> list = Arrays.asList(1, 2, 4);
//        System.out.println(list.get(3)); //ArrayIndexOutOfBoundsException: 3

        //2、多个异常一次捕获,多次处理
//        try {
    
    
//            int[] arr = {1, 2, 3};
//            System.out.println(arr[3]);
//        } catch (ArrayIndexOutOfBoundsException e) {
    
    
//            System.out.println(e);
//        } catch (IndexOutOfBoundsException e) {
    
    
//            System.out.println(e);
//        }
//        /*
//            一个try多个catch注意事项:
//                catch里边定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上边,否则就会报错
//         */
//        System.out.println("后续代码");

        //3、多个异常一次捕获,一次处理
        try {
    
    
            int[] arr = {
    
    1, 2, 3};
            System.out.println(arr[3]);
        } catch (ArrayIndexOutOfBoundsException e) {
    
    
            System.out.println(e);
        } catch (IndexOutOfBoundsException e) {
    
    
            System.out.println(e);
        }

    }
}

3、异常注意事项——finally里面有return

如果finally有return语句,永远返回finally中的结果,避免该情况。

public class Demo03Exception {
    
    
    public static void main(String[] args) {
    
    
        int a = getA();
        System.out.println(a); //100

    }
    //定义一个方法,返回变量a的值
    public static int getA() {
    
    
        int a = 10;
        try {
    
    
            return a;
        }catch (Exception e) {
    
    
            System.out.println(e);
        }finally {
    
    
            //一定会执行的代码
            a = 100;
            return a;
        }
    }
}

4、异常注意事项——子父类异常

如果父类抛出了多个异常,子类重写父类该方法时,抛出和父类相同的异常或者不抛出异常。
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出。

/*
    子父类的异常
    注意:
        父类异常什么样,子类异常什么样
 */
public class Fu {
    
    
    public void show01() throws NullPointerException, ClassCastException{
    
    }
    public void show02() throws IndexOutOfBoundsException{
    
    }
    public void show03() throws IndexOutOfBoundsException{
    
    }
    public void show04(){
    
    }
}

class Zi extends Fu{
    
    
    //子类重写父类方法时,抛出和父类相同的异常
    public void show01() throws NullPointerException, ClassCastException {
    
    }

    //子类重写父类方法时,抛出父类异常的子类
    public void show02() throws ArrayIndexOutOfBoundsException{
    
    }

    //子类重写父类方法时,不抛出异常
    public void show03(){
    
    }

    //父类方法不抛出异常,子类重写父类该方法时也不可抛出异常
    public void show04(){
    
    }
}

5、自定义异常类

自定义异常类:
java提供的异常类,不够我们使用,需要自己定义一些异常类
格式:

public class XXXException extends Exception / RuntimeException{
    
    
	添加一个空参数的构造方法
	添加一个带异常信息的构造方法
}

注意:
1、自定义异常类一般都是以Exception结尾,说明该类是一个异常类
2、自定义异常类,必须得继承Exception或者RuntimeException
a、继承Exception,那么自定义的异常类就是一个编译器异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try…catch
b、继承RuntimeException,那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)

6、小练习

import java.util.Scanner;

/*
    要求:模拟注册操作,如果用户名已存在,则抛出异常并提示:该用户名已经被注册

    分析:
        1、使用数组保存已经被注册过的用户名(数据库)
        2、使用Scanner获取用户输入的注册的用户名进行判断(前端,页面)
        3、定义一个方法,对用户输入的注册的用户名进行判断
            遍历存储已经注册过用户名的数组,获取每一个用户名
            使用获取到的用户名和用户输入的用户名比较
                true:
                    用户名已经存在,抛出异常RegisterException
                false:
                    继续遍历比较
            如果循环结束,还没有找到重复的用户名,提示用户:恭喜您,注册成功
 */
public class DemoRegisterException {
    
    
    static String[] usernames = {
    
    "张三", "李四", "王五"};

    public static void main(String[] args) /*throws RegisterException*/ {
    
    
        //使用Scanner获取用户输入的注册的用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要注册的用户名");
        String username = sc.next();
        checkUsername(username);
    }

    //3、定义一个方法,对用户输入的用户名进行判断
    public static void checkUsername(String username) /*throws RegisterException*/ {
    
    
        //遍历已经注册过用户名的数组,获取每一个用户名
        for (String name : usernames) {
    
    
            //使用获取的用户名和输入的比较
            if (name.equals(username)) {
    
    
                //true 用户名存在抛出异常
                try {
    
    
                    throw new RegisterException("该用户已经被注册");
                } catch (RegisterException e) {
    
    
                    e.printStackTrace();
                    return; //结束方法
                }

            }
        }

        //如果循环结束,还没有找到重复的用户名,提示用户:恭喜您,注册成功
        System.out.println("恭喜您,注册成功");
    }

}

运行截图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Gaoju12138/article/details/109496012
今日推荐