一文带你深入认识JAVA中的异常

 更新时间:2024年06月18日 10:00:24   作者:robin_suli  
Java异常处理成为社区中讨论最多的话题之一,下面这篇文章主要给大家介绍了关于JAVA中异常的相关资料,文中通过代码介绍的非常详细,对大家学习或者使用java具有一定的参考借鉴价值,需要的朋友可以参考下

一. 异常概念与体系结构:

1 异常的概念:在 Java 中,将程序执行过程中发生的 不正常行为 称为异常,

如:算数异常: ArithmeticException

System.out.println(10 / 0);
// 执行结果
Exception in thread "main" java.lang.ArithmeticException: / by zero

数组越界异常:ArrayIndexOutOfBoundsException

int[] arr = {1, 2, 3};
System.out.println(arr[100]);
// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100

空指针异常: NullPointerException

int[] arr = null;
System.out.println(arr.length);
// 执行结果
Exception in thread "main" java.lang.NullPointerException

2.异常的体系结构:异常种类繁多,为了对不同异常或者错误进行很好的分类管理, Java 内部维护了一个 异常的体系结构 如图:

从图中可以看出:

(1).Throwable : 是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception

(2). Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError和OutOfMemoryError,一旦发生回力乏术。

(3).Exception : 异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说的异常就是Exception。

OutOfMemoryError为内存泄漏 :程序中存在未释放的内存资源,导致内存占用不断增加,最终导致内存不足等等

StackOverflowError为:无限递归下去导致, 超出栈的容量等等

3. 异常的分类:分为 编译时异常,  运行时异常。

(1). 编译时异常:  在程序 编译期间 发生的异常,称为 编译时异常 ,也称为 受检查异常

如图:这个重写,克隆方法的拷贝,没有对其捕获或声明

下图则是声明: 就编译通过

2. 运行时异常:

(1) 在程序 执行期间 发生的异常,称为运行时异常,也称为 非受检查异常

(2)RunTimeException以及其子类对应的异常,都称为运行时异常。

比如NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException。

注意:编译时出现的语法性错误,不能称之为异常。例如将 System.out.println 拼写错了, 写成了

这里也用克隆举例子,这里没有实现克隆接口,却编译通过了!!!

但是运行会有异常:这就是非受查异常

二. 异常的处理:

在Java中, 异常处理主要的 5 个关键字: throw 、 try 、 catch 、 final 、 throws 。用好他们就,可以很好的处理异常了。

1. 异常的抛出 :在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者

注意:

(1). throw必须写在方法体内部

(2). 抛出的对象必须是Exception 或者 Exception 的子类对象

(3). 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理

(4). 如果抛出的是编译时异常,用户必须处理,否则无法通过编译

(5). 异常一旦抛出, 其后 的代码就不会执行。

如图:这里还用了,try处理catch捕捉

public static void main(String[] args)throws ArrayIndexOutOfBoundsException {
        int[] array = new int[2];

        //捕捉异常
        try {
            //放可能发生的异常
            System.out.println(array[3]);
            System.out.println("这里不会再执行了");

        }catch (ArrayIndexOutOfBoundsException e) {
            //捕捉异常
            System.out.println("处理了ArrayIndexOutOfBoundsException异常");
            //捕捉,打印异常
            e.printStackTrace();

        }
    }

2.异常的捕获:异常的捕获,也就是异常的具体处理方式,主要有两种: 异常声明throws 以及 try-catch捕获处理。

抛出异常:

public static void OpenConfig(String filename) throws FileNotFoundException {

        if (filename.equals("config.ini")) {
            throw new FileNotFoundException("配置文件名字不对");
        }
    }

3.try-catch 捕获并处理 :throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch。)

此时声明一下,然后捕获:( 直接声明不捕获也可以 )

class Exception {
    File file;

    /*
    FileNotFoundException : 编译时异常,表明文件不存在
    此处不处理,也没有能力处理,应该将错误信息报告给调用者,让调用者检查文件名字是否给错误了
    */
    public static void OpenConfig(String filename) throws FileNotFoundException {

        if (filename.equals("config.ini")) {
            throw new FileNotFoundException("配置文件名字不对");
        }
    }

    //捕获
    public static void main(String[] args) {
        try {
            //将可能出现异常的代码放在这里
            OpenConfig("test");
        } catch (FileNotFoundException e) {
            // 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基就会时,就会被捕获到
            e.printStackTrace();
        }finally {
            // 此处代码一定会被执行到,一般用来关闭文件,释放资源
        }

    }
}

注意:1.try块内抛出异常位置之后的代码将不会被执行。

2. 如果 抛出异常类型与catch时异常类型不匹配 ,即异常不会被成功捕获,也就不会被处理,继续往外抛 ,直到 JVM收到后中断程序。 (一般写法是,用父类异常在最后面兜底)

4.finally:

在写程序时, 有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源 :网络连接、数据库连接、IO 流等, 在程序正常或者异常退出时,必须要对资源进进行回收 。另外,因为 异常会引发程序的跳转,可能导致有些语句执行不到 , finally 就是用来解决这个问题的。

还有 finally 中的代码一定会执行的,一般在 finally 中进行一些资源清理的扫尾工作

语法格式:
try{
// 可能会发生异常的代码
}catch(异常类型 e){
// 对捕获到的异常进行处理
}finally{
// 此处的语句无论是否发生异常,都会被执行到
}
// 如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

(补充)异常的处理流程: 如果本方法中没有合适的处理异常的方式, 就会沿着调用栈向上传递 ( 方法1--》方法2--》方法3---》main方法----》jvm)

三. 自定义异常类:

Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构.就需要自定义异常

例如, 我们实现一个用户登陆功能:

根据业务此时我们在处理用户名密码错误的时候可能就需要抛出两种异常

注意:

1.自定义异常类,然后继承自Exception 或者 RunTimeException

2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因

业务代码:

class login {
    private String userName;
    private String passWord;

    public  void loginFo(String userName, String passWord)throws UserException,PassWardException{
        if (!this.userName.equals(userName)) {
            throw new UserException("抛出自定义,的用户名错误异常");

        }

        if (!this.passWord.equals(passWord)) {
            
            throw new PassWardException("抛出密码自定义,的用密码错误异常");

        }

        System.out.println("登录成功!");
    }


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
}

public class TestException {
    public static void main(String[] args) throws UserException {
        login login = new login();
        login.setPassWord("321");
        login.setUserName("haha");
        login.loginFo("haha", "323");

        /*try {
            login.loginFo("haha", "323");

        }catch (UserException e) {
            e.printStackTrace();
        }catch (PassWardException e) {
            e.printStackTrace();
        }finally {

        }*/
    }
}

总结

到此这篇关于JAVA中异常的文章就介绍到这了,更多相关JAVA异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Logback日志保存到相对路径的操作

    使用Logback日志保存到相对路径的操作

    这篇文章主要介绍了使用Logback日志保存到相对路径的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • JAVA中使用FTPClient实现文件上传下载实例代码

    JAVA中使用FTPClient实现文件上传下载实例代码

    本文给大家介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件。非常不错具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-06-06
  • IntelliJ IDEA的代码搁置功能实现

    IntelliJ IDEA的代码搁置功能实现

    本文主要介绍了IntelliJ IDEA的代码搁置功能实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • MyBatis中 @Mapper 和 @MapperScan 的区别与使用解析

    MyBatis中 @Mapper 和 @MapperScan 的区别与使用解析

    本文介绍了SpringBoot中MyBatis的两个常用注解:@Mapper和@MapperScan,@Mapper用于标记单个Mapper接口,而@MapperScan用于批量扫描指定包下的所有Mapper接口,两者都有各自适用的场景,选择合适的注解可以提高开发效率并使代码更加简洁,感兴趣的朋友一起看看吧
    2025-01-01
  • Java应用层协议WebSocket实现消息推送

    Java应用层协议WebSocket实现消息推送

    后端向前端推送消息就需要长连接,首先想到的就是websocket,下面这篇文章主要给大家介绍了关于java后端+前端使用WebSocket实现消息推送的详细流程,需要的朋友可以参考下
    2023-02-02
  • Java转换流(InputStreamReader/OutputStreamWriter)的使用

    Java转换流(InputStreamReader/OutputStreamWriter)的使用

    本文主要介绍了Java转换流(InputStreamReader/OutputStreamWriter)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • JAVA关键字及作用详解

    JAVA关键字及作用详解

    本文主要介绍了Java关键字及作用,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • java求两个数中的大数(实例讲解)

    java求两个数中的大数(实例讲解)

    下面小编就为大家带来一篇java求两个数中的大数(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 虚拟机linux中jdk安装配置方法

    虚拟机linux中jdk安装配置方法

    这篇文章主要为大家详细介绍了虚拟机linux中jdk安装配置方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • java中的DateTime的具体使用

    java中的DateTime的具体使用

    本文主要介绍了java中的DateTime的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论