12. Java异常及异常处理处理

Java ------ 异常及处理

        • [1. 异常](#1. 异常)
        • [2. 异常体系](#2. 异常体系)
        • [3. 常见Exception](#3. 常见Exception)
        • [4. 异常处理](#4. 异常处理)
          • [4.1 try finally catch关键字](#4.1 try finally catch关键字)
          • [4.2 throws和throw 自定义异常](#4.2 throws和throw 自定义异常)
          • [4.3 finally,final,finalize三者的区别](#4.3 finally,final,finalize三者的区别)
1. 异常

|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 异常:在程序执行过程中发生的意外状况,可能导致程序中断或产生错误结果 异常对象:java(面向对象)将错误用类来描述,一旦程序执行错误,将会创建对应的错误对象(用以向程序员或用户展示错误原因等) 异常处理的意义:提高代码的健壮性和可靠性,使程序可以处理非预期的情景,并且继续正常的处理 |

2. 异常体系

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 异常超类:Thorwable类(表示可抛出)是所有异常和错误的超类 异常的两个子类:Exception异常类,Error错误异常类 Exception程序捕捉处理的异常:表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常 Error系统错误:表示Java运行时环境出现的错误(JVM内存资源耗尽) |

  • java异常体系图

Throwable的父类也是Object,继承其父类的 getClass()和getName()方法

  • 常用方法
java 复制代码
// 返回抛出异常的详细信息
public string getMessage();
public string getLocalizedMessage();
//返回异常发生时的简要描述
public public String toString()
//打印异常信息到标准输出流上
public void printStackTrace();
public void printStackTrace(PrintStream s);
public void printStackTrace(PrintWriter s)
//记录栈帧的的当前状态
public synchronized Throwable fillInStackTrace();
java 复制代码
package exception;

/**
 * 常见使用方法
 */
public class ExceptionAPI {
    public static void main(String[] args) {
        System.out.println("程序开始!");
        try {
            String line = "1i0";
            System.out.println(Integer.parseInt(line));
        } catch (NumberFormatException e) {
            // 显示红色报错信息
            e.printStackTrace();
            // 获取错误信息
            System.out.println("错误信息:" + e.getMessage());
            System.out.println("错误信息Localized:" + e.getLocalizedMessage());

            System.out.println("简要描述:" + e.toString());
            System.out.println("当前状态:" + e.fillInStackTrace());
        }
        System.out.println("结束");
    }
}
3. 常见Exception

|-------------------------------------------------------------------------|
| Exception的两类异常:RuntimeException运行时异常(非受控),CheckedException编译时异常(受控) |

常见UncheckedException异常

异常 异常描述
ArrayIndexOutOfBoundsException 数组越界异常
NulPointerException 空指针异常
llegalArgumentException 非法参数异常
NegativeArraySizeException 数组长度为负异常
llegalStateException 非法状态异常
ClassCastException 类型转换异常

常见RuntimeException异常

异常 异常描述
NoSuchFieldException 表示该类没有指定名称抛出来的异常
NoSuchMethodException 表示该类没有指定方法抛出来的异常
llegalAccessException 不允许访问某个类的异常
ClassNotFoundException 类没有找到抛出异常
4. 异常处理
4.1 try finally catch关键字

组合:try...catch 对某一段代码可能抛出异常进行的捕获

try...finally 对一段代码不管执行情况如何,都会走finally中的代码

try...catch...finally 对异常捕获后,再走fimally中的代码逻辑

  • 异常处理过程:一般是子类型在前,超类型在后

对指定代码内容添加一定包围功能(try...finally)快捷键:ctrl+alt+t
try...catch

java 复制代码
package exception;
/**
 * java异常处理机制
 * java异常超类:Throwable
 * 两个子类:Error,表示系统级别错误
 */
public class TryCatch {
    public static void main(String[] args) {
        System.out.println("程序开始执行!");
        // try catch异常处理
        try{
            String line = "";
//             String line = null;
            System.out.println(line.length());
            System.out.println(line.charAt(0));
        } catch (NullPointerException e){
            // 程序没有异常就不会执行该异常处理
            System.out.println("异常:空指针异常!");
        } catch (StringIndexOutOfBoundsException e){
            // try中的代码执行捕获到第一个异常之后,直接跳到相应的处理机制,后面的异常将不再执行
            System.out.println("异常:索引超出范围!");
        } catch (NoSuchFieldError | StackOverflowError e){
            // 多个异常的相同处理机制
            System.out.println("发生异常!");
        } catch (Exception e){
            // 超类异常(多种异常,超类异常一般写在最后)
            System.out.println("出错!");
        }
        System.out.println("执行完毕!");
    }
}

try...catch...finally

java 复制代码
package exception;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * finally 关键字用来创建在 try 代码块后面执行的代码块
 * 无论是否发生异常,finally 代码块中的代码总会被执行
 * 在 finally 代码块中,可以运行清理类型等收尾善后性质的语句
 *
 * @author LongYongchuan
 */
public class FinallyDemo {
    public static void main(String[] args) {
        System.out.println("程序开始!");
        try{
            String line = "11";
            System.out.println(line.length());
        } catch (Exception e) {
            System.out.println("出错了!");
        } finally {
            System.out.println("finally");
        }
        System.out.println("程序结束!");

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("./document/fos.txt");
            fos.write(5);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

编译器的自动关闭特性(只是编译器认可)

  • 只有实现了AutoCloseable接口的类才能在try后面加(进行初始化),java中所有流都实现了该接口
java 复制代码
package exception;

import java.io.FileOutputStream;
import java.io.IOException;

public class AutoClose {
    public static void main(String[] args) {
        // 编译器优化代码(只有实现了AutoCloseable接口的类)
        try (
                // 初始化
                FileOutputStream fos = new FileOutputStream("./document/fos.dat")
        ) {
            fos.write(1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4.2 throws和throw 自定义异常

Java中,异常就是一个对象,它能够被程序员自定义抛出或者应用程序抛出,必须借助于throws和throw 语句来定义抛出异常

throws和throw通常是成对出现的:

throws 语句用在方法声明后面,表示再抛出异常,由该方法的调用者来处理,抛出一个异常实例

throw语句用在方法体内,表示抛出异常,由方法体内的语句处理

  • 自定义异常
  • Java异常机制可以保证程序更安全和更健壮,虽然Java类库已经提供很多可以直接处理异常的类,但是有时候为了更加精准地捕获和处理异常以呈现更好的用户体验,需要开发者自定义异常
  • 自定义异常
    1.类名要做到见名知义
    2.必须继承自Exception(直接或间接继承)
    3.提供从超类异常定义的所有构造器
    1. throw和throws通常成对出现(单独的throw对Exception时编译不通过,需要使用throws在方法上对异常抛出处理)
    2. 一般RuntimeException和throw使用,其他异常需结合throw和throws使用,一般不要在main方法上抛出异常(不负责的体现)
    3. 方法中出现throw异常时,throw后面的代码将不执行,而直接进入异常处理机制
  • 自定义异常
java 复制代码
package exception;

public class IllegalAgeException extends Exception{
    // alt+insert键生成
    public IllegalAgeException() {
    }

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

    public IllegalAgeException(String message, Throwable cause) {
        super(message, cause);
    }

    public IllegalAgeException(Throwable cause) {
        super(cause);
    }

    public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
  • 抛出异常
java 复制代码
package exception;

public class Person{
    private String name;
    private int age;
    private char gender;
    private String[] otherInfo;

    public Person() {
    }

    public Person(String name, int age, char gender, String[] otherInfo) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.otherInfo = otherInfo;
    }

    public String getName() {
        return name;
    }

    // 异常处理throws关键字(使用在方法声明之后,抛出异常处理,该异常由方法调用者处理)
    public void setName(String name){
        if (name.length() <= 0 || name.length() >= 5){
            // throw和throws通常成对出现(单独的throw对Exception时编译不通过,需要使用throws在方法上对异常抛出处理)
            throw new RuntimeException("名字长度不符合汉文名字");
        }
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws IllegalAgeException{
        // 抛出异常throw关键字
        if (age < 0 || age >100){
            // 一般RuntimeException和throw使用,其他异常需结合throw和throws使用
            throw new IllegalAgeException("年龄不合法");
            // 出现异常时,throw相当于return直接结束,不执行this.age = age;
        }
        this.age = age;
        System.out.println("年龄:" + age);
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public String[] getOtherInfo() {
        return otherInfo;
    }

    public void setOtherInfo(String[] otherInfo) {
        this.otherInfo = otherInfo;
    }

}
  • 异常处理
java 复制代码
package exception;

/**
 * throw关键字
 */
public class ThrowDemo {
    // 一般不要在main方法上抛出异常
    public static void main(String[] args){
        Person person = new Person();
        // throw单独的异常一般不必须抛出
        person.setName("萨克");

        // 使用throw和throws抛出的异常必须处理
        try {
            // 方法调用者处理异常
            person.setAge(50);

        } catch (IllegalAgeException e) {
            throw new RuntimeException(e);
        }
        System.out.println("此人姓名:" + person.getName());
    }
}

注:

允许子类方法抛出父类方法的部分异常

允许子类方法不再抛出异常

允许子类方法抛出父类方法声明的子类型异常


不允许子类方法抛出额外异常

不允许子类方法抛出父类方法声明异常的超类型异常

4.3 finally,final,finalize三者的区别
  • finally 关键字用于定义在 try-catch 语句块中始终执行的代码块
  • final 关键字用于修饰类、方法和变量,分别表示最终类、最终方法和常量
  • finalize() 方法是 Object 类中的方法,用于对象在被垃圾回收前进行资源清理的操作
  1. finallyfinally 是 Java 中的一个关键字,用于定义在 try-catch 语句块中的一个代码块。无论是否发生异常,finally 代码块始终会被执行(常用于进行清理工作,例如关闭文件、释放资源等)
java 复制代码
try {
    // 可能引发异常的代码
} catch (Exception e) {
    // 异常处理逻辑
} finally {
    // 始终会执行的代码,用于清理工作
}
  1. finalfinal 是用来修饰类、方法和变量的关键字
  • 当用 final 修饰一个类时,表示该类不能被继承,即该类为最终类
  • 当用 final 修饰一个方法时,表示该方法不能被子类重写,即该方法为最终方法
  • 当用 final 修饰一个变量时,表示该变量的值不能被修改,即该变量为常量
java 复制代码
final class FinalClass {
    // 最终类,不能被继承
}

class SuperClass {
    final void finalMethod() {
        // 最终方法,不能被重写
    }
}

public class Example extends SuperClass {
    // 尝试重写finalMethod()会导致编译错误
}

class MyClass {
    final int MAX_VALUE = 10; // 常量,不能被修改
}
  1. finalize()finalize() 是 Object 类中的一个方法,用于在对象被垃圾回收前进行资源清理的操作。当垃圾回收器准备回收一个对象时,会先调用其 finalize() 方法(如果该对象重写了该方法),然后才对其进行垃圾回收。通常用于释放非Java堆内存资源,如关闭文件、释放连接等。但是,它已经过时,不推荐使用。
java 复制代码
class MyClass {
    @Override
    protected void finalize() throws Throwable {
        // 对象的资源清理操作
    }
}
相关推荐
西猫雷婶23 分钟前
python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶
开发语言·python·opencv
kiiila24 分钟前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
初晴~24 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾1 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
老刘莱国瑞1 小时前
STM32 与 AS608 指纹模块的调试与应用
python·物联网·阿里云
黑胡子大叔的小屋1 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark1 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
唐 城1 小时前
curl 放弃对 Hyper Rust HTTP 后端的支持
开发语言·http·rust
一只敲代码的猪2 小时前
Llama 3 模型系列解析(一)
大数据·python·llama