要从一座山攀上另一座更高的山,第一步便是下山

                                                                   —— 24.5.3

知识回顾:

1.权限修饰符

        public -> protected -> 默认 -> private

        a、构造方法一般用public:便于new对象

        b、成员方法一般用public:便于调用

        c、成员变量的属性一般用private:封装思想

2.final:最终的

        a、修饰类:不能被继承的

        b、修饰方法:不能被重写的

        c、修饰局部变量:不能被二次赋值

        d、修饰对象:地址值不能改变,但是对象中的属性值可以改变

        e、修饰成员变量:需要手动赋值,不能二次赋值

3.代码块

        a、构造代码块:

                {}

                优先于构造方法执行,每new一次,构造代码块就执行一次

        b、静态代码块:

 

一、异常介绍以及出现过程

1.概述

        代码出现了不正常的现象,在java中,异常都是一个一个的类

2.Error和Exception

        Error:错误 代码出现了重大错误,相当于人得了绝症,需要重写代码,需要大的改动

        Exception:异常 代码出现了小的问题,相当于小感冒

3.异常Exception的分类

        ① 编译时期异常 —— 代码一写一编译,爆红了(语法错误除外)

                                           Exception以及子类(除了RuntimeExeption及其子类之外都属于编译时期异常,包括Exception)

        ② 运行时期的异常 —— 写代码的时候不爆红,一运行就是错误的

                                               RuntimeException以及子类

4.示例

        运行时期异常

public class Demo145Exception {
    public static void main(String[] args) {
        // 错误Error
//        method();
        // 运行时期异常
        int[] arr1 = new int[3];
        System.out.println(arr1[4]);
    }

    public static void method(){
        method();
    }
}

        编译时期异常

public class Demo145Exception {
    public static void main(String[] args) {
        // 编译时期异常
        // 编译时期的异常是调用方法时,该方法底层给我们抛了一个编译时期异常,所以导致我们一调用此方法就爆红了
        // 当我们一旦触发了这个异常,jvm就会将异常信息打印到控制台上,给程序员们看
        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = "2002-11-04";
        Date date = sdf.parse(time);
        System.out.println(date);
    }
}

public class Demo146Exception2 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        method(arr);
    }

    public static void method(int[] arr){
        System.out.println(arr[6]);
        System.out.println("我想要执行");
    }
}

5.异常处理过程

二、创建异常对象(自己造异常)

创建异常对象,只是为了学习如何处理异常,其他的暂时没有什么意义

1.关键字

        throw

2.格式

        throw new 异常

3.示例

public class Demo147Exception3 {
    public static void main(String[] args) {
        String s = "a.txt";
        method(s);
        String ss = "a.txit";
        method(ss);
    }

    public static void method(String s){
        if (!s.endsWith(".txt")){
            // 故意创建异常对象,用throw说明此处有异常
            throw new NullPointerException();
        }
        System.out.println("我要执行了");
    }
}

三、异常处理的两种方式

1.异常处理方式1 —— throws

        格式:

                在方法参数和方法体之间位置上写

        意义:

                处理异常,将异常往上抛,最终还是给jvm,jvm将异常信息打印终止程序

        示例:

        所有功能都无法使用,不能无脑进行throws,无脑throws不负责任

package S55Exception;

import java.io.FileNotFoundException;

public class Demo148Exception4 {
    public static void main(String[] args) throws FileNotFoundException{
        String s = "a.txt";
        String s1 = "a";
        add(s1);   //出现了异常 Exception in thread "main" java.io.FileNotFoundException: 文件找不到
        add(s); // 添加功能
        delete();   // 删除功能
        update();   // 修改功能
        find(); // 查询功能
    }

    private static void add(String s)throws FileNotFoundException {
        if (!s.endsWith(".txt")){
            // 故意创造一个异常 属于编译时期的异常
            throw new FileNotFoundException("文件找不到");
        }
        System.out.println("我要执行了");
    }

    private static void find() {
        System.out.println("查询功能");
    }

    private static void update() {
        System.out.println("修改功能");
    }

    private static void delete() {
        System.out.println("删除功能");
    }
}

2.异常处理方式1——throws多个异常

        格式:

                throws 异常1,异常2

        注意:

                如果throws的多个异常之间有子夫类继承关系,我们可以直接throws父类异常

        

package S55Exception;

import java.io.FileNotFoundException;
import java.io.IOException;

public class Demo149Exception5 {
    public static void main(String[] args) throws /*FileNotFoundException*/Exception {
        String s = "a.txt";
        String s1 = "a";
        add(s1);   //出现了异常 Exception in thread "main" java.io.FileNotFoundException: 文件找不到
        add(s); // 添加功能
        delete();   // 删除功能
        update();   // 修改功能
        find(); // 查询功能
    }

    private static void add(String s)throws /*FileNotFoundException*/ IOException{
        if(s==null){
            // 故意造异常
            throw new IOException("IO异常");
        }
        if (!s.endsWith(".txt")){
            // 故意创造一个异常 属于编译时期的异常
            throw new FileNotFoundException("文件找不到");
        }
        System.out.println("我要执行了");
    }

    private static void find() {
        System.out.println("查询功能");
    }

    private static void update() {
        System.out.println("修改功能");
    }

    private static void delete() {
        System.out.println("删除功能");
    }
}

3.异常处理方式2 —— try...catch

        格式:

                try{

                        可能出现异常的代码

                }catch(异常 对象名){

                        处理异常的代码 -> 将来开发会将异常信息保存在日志文件中

                }

        示例:
    public static void main(String[] args) {
        String s = "a.txt";
        String s1 = "a";
        try{
            add(s); //添加功能
        }catch (FileNotFoundException e){
            System.out.println(e);
        }
        try{
            add(s1); //添加功能
        }catch (FileNotFoundException e){
            System.out.println(e);
        }
        delete();   // 删除功能
        update();   // 修改功能
        find(); // 查询功能
    }

    private static void add(String s)throws FileNotFoundException {
        if (!s.endsWith(".txt")){
            // 故意创造一个异常 属于编译时期的异常
            throw new FileNotFoundException("文件找不到");
        }
        System.out.println("我要执行了");
    }

    private static void find() {
        System.out.println("查询功能");
    }

    private static void update() {
        System.out.println("修改功能");
    }

    private static void delete() {
        System.out.println("删除功能");
    }

4.异常处理方式2_多个异常

        格式:

                try{

                        可能出现异常的代码

                }catch(异常 对象名){

                        处理异常的代码 -> 将来开发会将异常信息保存在日志文件中

                }catch(异常 对象名){

                        处理异常的代码 -> 将来开发会将异常信息保存在日志文件中

                }catch(异常 对象名){

                        处理异常的代码 -> 将来开发会将异常信息保存在日志文件中

                }…

        示例:
package S55Exception;

import java.io.FileNotFoundException;
import java.io.IOException;

public class Demo151Exception7 {
    public static void main(String[] args) {
        String s = "null";
        try{
            add(s);// 添加功能
        }catch (FileNotFoundException e) {
            System.out.println(e);
        }catch (IOException e){
            System.out.println(e);
        }
        delete();   // 删除功能
        update();   // 修改功能
        find(); // 查询功能
    }

    private static void add(String s)throws FileNotFoundException,IOException{
        if(s==null){
            // 故意造异常
                throw new IOException("IO异常");
        }
        if (!s.endsWith(".txt")){
            // 故意创造一个异常 属于编译时期的异常
            throw new FileNotFoundException("文件找不到");
        }
        System.out.println("我要执行了");
    }

    private static void find() {
        System.out.println("查询功能");
    }

    private static void update() {
        System.out.println("修改功能");
    }

    private static void delete() {
        System.out.println("删除功能");
    }
}

        注意:

                如果catch的多个异常之间存在父类继承关系,我们可以直接catch父类异常

                如果不知道多个异常间是否有子父类继承关系,我们都可以直接catch Exception

四、finally关键字

        概述

                代表的是不管是否触发了异常,都会执行的代码块

                特殊情况:如果之前执行了System.exit(0),终止当前正在执行的java虚拟机

        使用:

                都是配合try...catch使用
         try{
                可能出现异常的代码
        }catch(异常 对象名){
                处理异常的代码->将来开发会将异常信息保存到日志文件中

        }finally{
                不管是否有异常,都会执行的代码

        }

        示例:
    public static void main(String[] args) {
        String s = "a.txt1";
        try {
            add(s); // 添加功能
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            System.out.println("我必须执行");
        }
    }

    private static void add(String s)throws FileNotFoundException {
        if (!s.endsWith(".txt")){
            // 故意创造一个异常 属于编译时期的异常
            throw new FileNotFoundException("文件找不到");
        }
        System.out.println("我要执行了");
    }

public class Demo153Exception9 {
    public static void main(String[] args) {
        int result = method();
        System.out.println(result);
    }

    public static int method(){
        try {
            String s = null;
            System.out.println(s.length());// 空指针异常
            return 2;
        }catch (Exception e){
            return 1;    // return 1 代表的是将1返回,结束方法
        }finally {
            System.out.println("我一定要执行");
        }
    }

无论方法结束与否,finally一定要执行

public class Demo153Exception9 {
    public static void main(String[] args) {
        int result = method();
        System.out.println(result);
    }

    public static int method(){
        try {
            String s = null;
            System.out.println(s.length());// 空指针异常
            return 2;
        }catch (Exception e){
            return 1;
        }finally {
            System.out.println("我一定要执行");
            return 3;
        }
    }

        使用场景:

                1.关闭资源

                2.原因:对象如果没有用了,GC(垃圾回收器)回收,用来回收堆内存中的垃圾,释放内存,但是有一些对象GC回收不了,比如:链接对象(Connection),IO流对象,Socket对象,这些对象GC回收不了,需要我们自己手动回收,手动关闭

                将来不能回收的对象new完之后,后续操作不管是否操作成功,是否有异常,我们都需要手动关闭,此时我们就可以将关闭资源的代码放在finally中

抛异常时注意的事项

        1.如果父类中的方法抛了异常,那么子类重写之后要不要抛?

                可抛可不抛

        2.如果父类中的方法没有抛异常,那么子类重写之后要不要抛?

                不要抛

try_catch和throws的使用实际时机

        1.如果处理异常之后,还想让后续的代码正常执行,我们使用try...catch
        2.如果方法之间是递进关系(调用),我们可以先throws,但是到了最后需要用try...catch做一个统一的异常处理

        异常处理流程:

① 编译时期的异常必须立马处理,否则会报错报红

        a、throws

        b、try…catch

② 运行时期异常我们一般不处理,一旦出现运行时期异常,肯定是代码写得问题,我们直接修改代码细节即可

五、自定义异常

1.需求:键盘录入一个用户名,实现登录功能,如果登录失败,抛出 LoginuserException

import javax.security.auth.login.LoginException;
import java.util.Scanner;

public class Demo155Exception11 {
    public static void main(String[] args) throws LoginUserException {
        // 1.定义一个用户名,代表已经注册的用户
        String username = "root";
        // 2.创建Scanner对象,录入用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的用户名:");
        String name = sc.next();
        // 3.判断用户名是否和已经存在的用户名一致
        if(name.equals(username)){
            System.out.println("登陆成功");
        }else{
            // 利用有参构造给异常写原因
            throw new LoginUserException("登陆失败了,用户名或者密码有问题");
        }
    }
public class LoginUserException extends Exception{
    public LoginUserException() {
    }

    public LoginUserException(String message) {
        super(message);
    }
}

        ① 定义一个类

        ② 如果继承Exception 就是编译时期的异常

        ③ 如果继承RuntimeException,就是运行时期异常

六、打印异常信息的三个方法

① toString

    public static void main(String[] args) {
        // 1.定义一个用户名,代表已经注册的用户
        String username = "root";
        // 2.创建Scanner对象,录入用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的用户名:");
        String name = sc.next();
        // 3.判断用户名是否和已经存在的用户名一致
        if(name.equals(username)){
            System.out.println("登陆成功");
        }else{
            // 利用有参构造给异常写原因
            try {
                throw new LoginUserException("登陆失败了,用户名或者密码有问题");
            }catch (Exception e){
                System.out.println(e.toString());
            }
        }
    }

② getMessage

    public static void main(String[] args) {
        // 1.定义一个用户名,代表已经注册的用户
        String username = "root";
        // 2.创建Scanner对象,录入用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的用户名:");
        String name = sc.next();
        // 3.判断用户名是否和已经存在的用户名一致
        if(name.equals(username)){
            System.out.println("登陆成功");
        }else{
            // 利用有参构造给异常写原因
            try {
                throw new LoginUserException("登陆失败了,用户名或者密码有问题");
            }catch (Exception e){
//                System.out.println(e.toString());
                System.out.println(e.getMessage());
            }
        }
    }

③ printStackTrace

public class Demo155Exception11 {
    public static void main(String[] args) {
        // 1.定义一个用户名,代表已经注册的用户
        String username = "root";
        // 2.创建Scanner对象,录入用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的用户名:");
        String name = sc.next();
        // 3.判断用户名是否和已经存在的用户名一致
        if(name.equals(username)){
            System.out.println("登陆成功");
        }else{
            // 利用有参构造给异常写原因
            try {
                throw new LoginUserException("登陆失败了,用户名或者密码有问题");
            }catch (Exception e){
//                System.out.println(e.toString());
//                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

七、总结 

1.概述·代码出现了不正常的现象

2.分类

Throwable

        Error 错误
        Exception 异常
                编译时期异常

                        语法没有错误,调用某个方法,直接爆红(因为被调用的方法底层抛了一个编译时期异常)

                        Exception以及子类(除了RuntimeExceptionz外)
                运行时期异常,
                        语法没有错误,但是一运行就报错
                        RuntimeException以及子类
3.异常默认外理方案 —— 往上抛,最后给jvm,打印异常信息,终止程序

4.异常处理

        a.throws
        b.try...catch

5.finally

        不管有没有异常,都会执行的代码块

        配合try..catch使用
        使用场景:一般都是作为关闭资源使用的,关闭GC回收不了的对象

6.自定义异常

        a.定义一个类
                继承Exception,就是编译时期异常
                继承RuntimeException,就是运行时期异岸
        b.提供构造方法,用来设置异常信息

Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐