返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >全面了解java中的异常处理
  • 278
分享到

全面了解java中的异常处理

java异常处理 2020-09-26 21:09:21 278人浏览 绘本
摘要

目录Java 异常处理1. 什么是异常2. Java 异常类架构2.1 Throwable 类2.2 Error 类2.3 Exception 类3. 如何进行异常处理4. 抛出异常4.1 实例4.2 throw4.3 throws5. 捕

目录
  • Java 异常处理
    • 1. 什么是异常
    • 2. Java 异常类架构
      • 2.1 Throwable 类
      • 2.2 Error 类
      • 2.3 Exception 类
    • 3. 如何进行异常处理
      • 4. 抛出异常
        • 4.1 实例
        • 4.2 throw
        • 4.3 throws
      • 5. 捕获异常
        • 6. 自定义异常
          • 7. 异常链
            • 8. 小结

            Java 异常处理

            Java 的异常处理是 Java 语言的一大重要特性,也是提高代码健壮性的最强大方法之一。当我们编写了错误的代码时,编译器在编译期间可能会抛出异常,有时候即使编译正常,在运行代码的时候也可能会抛出异常。

            目标

            什么是异常

            Java 中异常类的架构

            如何进行异常处理

            如何自定义异常

            什么是异常链

            如何使用异常链

            前言

            8/25

            编程不能停,成为运维开发性人才

            计算机408基础打好,编程语言学精通,然后走下去

            Dockerk8s继续

            1. 什么是异常

            异常就是程序上的错误,我们在编写程序的时候经常会产生错误,这些错误划分为编译期间的错误运行期间的错误。

            下面我们来看几个常见的异常案例。

            如果语句漏写分号,程序在编译期间就会抛出异常,实例如下:

            
            public class Hello {
                public static void main(String[] args) {
                    System.out.println("Hello World!")
                }
            }
            

            运行结果:

            
            $ javac Hello.java
            Hello.java:3: 错误: 需要';'
                    System.out.println("Hello World!")
                                                      ^
            1 个错误
            

            static 关键字写成了 statci,实例如下:

            
            Hello.java:2: 错误: 需要<标识符>
                public statci void main(String[] args) {
                             ^
            1 个错误
            

            数组下标越界,程序在编译阶段不会发生错误,但在运行时会抛出异常。实例如下:

            
            public class ArrayOutOfIndex {
                public static void main(String[] args) {
                    int[] arr = {1, 2, 3};
                    System.out.println(arr[3]);
                }
            }
            

            运行结果:

            
            Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
            	at ArrayOutOfIndex.main(ArrayOutOfIndex.java:4)
            

            2. Java 异常类架构

            在 Java 中,通过 Throwable 及其子类来描述各种不同类型的异常。如下是 Java 异常类的架构图(不是全部,只展示部分类):

            img

            2.1 Throwable 类

            Throwable 位于 java.lang 包下,它是 Java 语言中所有错误(Error)和异常(Exception)的父类。

            Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。

            主要方法:

            • fillInStackTrace: 用当前的调用栈层次填充 Throwable 对象栈层次,添加到栈层次任何先前信息中;
            • getMessage:返回关于发生的异常的详细信息。这个消息在 Throwable 类的构造函数中初始化了;
            • getCause:返回一个 Throwable 对象代表异常原因;
            • getStackTrace:返回一个包含堆栈层次的数组。下标为 0 的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底;
            • printStackTrace:打印 toString() 结果和栈层次到 System.err,即错误输出流。

            2.2 Error 类

            ErrorThrowable 的一个直接子类,它可以指示合理的应用程序不应该尝试捕获的严重问题。这些错误在应用程序的控制和处理能力之外,编译器不会检查 Error,对于设计合理的应用程序来说,即使发生了错误,本质上也无法通过异常处理来解决其所引起的异常状况。

            常见 Error

            • AssertionError:断言错误;
            • VirtualMachineError虚拟机错误;
            • UnsupportedClassVersionError:Java 类版本错误;
            • OutOfMemoryError :内存溢出错误。

            2.3 Exception 类

            ExceptionThrowable 的一个直接子类。它指示合理的应用程序可能希望捕获的条件。

            Exception 又包括 Unchecked Exception(非检查异常)和 Checked Exception(检查异常)两大类别。

            2.3.1 Unchecked Exception (非检查异常)

            Unchecked Exception 是编译器不要求强制处理的异常,包含 RuntimeException 以及它的相关子类。我们编写代码时即使不去处理此类异常,程序还是会编译通过。

            常见非检查异常:

            • NullPointerException:空指针异常;
            • ArithmeticException:算数异常;
            • ArrayIndexOutOfBoundsException:数组下标越界异常;
            • ClassCastException:类型转换异常。
            2.3.2 Checked Exception(检查异常)

            Checked Exception 是编译器要求必须处理的异常,除了 RuntimeException 以及它的子类,都是 Checked Exception 异常。我们在程序编写时就必须处理此类异常,否则程序无法编译通过。

            常见检查异常:

            • IOException:IO 异常
            • sqlException:SQL 异常

            3. 如何进行异常处理

            在 Java 语言中,异常处理机制可以分为两部分:

            • 1.抛出异常:当一个方法发生错误时,会创建一个异常对象,并交给运行时系统处理;
            • 2.捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器。

            Java 通过 5 个关键字来实现异常处理,分别是:throwthrowstrycatchfinally

            异常总是先抛出,后捕获的。下面我们将围绕着 5 个关键字来详细讲解如何抛出异常以及如何捕获异常

            4. 抛出异常

            4.1 实例

            我们先来看一个除零异常的实例代码:

            
            package com.caq.exception;
            
            public class Demo01 {
                //打印a/b的结果
                public static void test(int a,int b){
                    System.out.println(a/b);
                }
            
                public static void main(String[] args) {
                    //调用test方法
                    test(5,0);
                }
            }
            

            运行结果:

            
            Exception in thread "main" java.lang.ArithmeticException: / by zero
            	at com.caq.exception.Demo01.test(Demo01.java:6)
            	at com.caq.exception.Demo01.main(Demo01.java:11)
            
            Process finished with exit code 1
            

            我们知道 0 是不能用作除数的,由于 test() 方法中除数 b0,所以代码将停止执行并显示了相关的异常信息,此信息为堆栈跟踪

            上面的运行结果告诉我们:main 线程发生了类型为 ArithmeticException 的异常,显示消息为 by zero,并且提示了可能发生异常的方法和行号。

            4.2 throw

            上面的实例中,程序在运行时引发了错误,那么如何来显示抛出(创建)异常呢?

            我们可以使用 throw 关键字来抛出异常,throw 关键字后面跟异常对象,改写上面的实例代码:

            
            package com.caq.exception;
            
            public class Demo01 {
                //打印a/b的结果
                public static void test(int a,int b){
                    if (b==0){
                        //抛出异常
                        throw new ArithmeticException("被除数不能为零");
                    }
                    System.out.println(a/b);
                }
            
                public static void main(String[] args) {
                    //调用test方法
                    test(5,0);
                }
            }
            

            运行结果:

            
            Exception in thread "main" java.lang.ArithmeticException: 被除数不能为零
            	at com.caq.exception.Demo01.test(Demo01.java:8)
            	at com.caq.exception.Demo01.main(Demo01.java:15)
            

            代码在运行时同样引发了错误,但显示消息为 “除数不能为零”。我们看到 test() 方法中加入了条件判断,如果调用者将参数 b 设置为 0 时,会使用 throw 关键字来抛出异常,throw 后面跟了一个使用 new 关键字实例化的算数异常对象,并且将消息字符串作为参数传递给了算数异常的构造函数。

            我们可以使用 throw 关键字抛出任何类型的 Throwable 对象,它会中断方法,throw 语句之后的所有内容都不会执行。除非已经处理抛出的异常。异常对象不是从方法中返回的,而是从方法中抛出的。

            4.3 throws

            可以通过 throws 关键字声明方法要抛出何种类型的异常。如果一个方法可能会出现异常,但是没有能力处理这种异常,可以在方法声明处使用 throws 关键字来声明要抛出的异常。例如,汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。

            throws 用在方法定义时声明该方法要抛出的异常类型,如下是伪代码:

            
            public void demoMethod() throws Exception1, Exception2, ... ExceptionN {
                // 可能产生异常的代码
            }
            

            throws 后面跟的异常类型列表可以有一个也可以有多个,多个则以 , 分割。当方法产生异常列表中的异常时,将把异常抛向方法的调用方,由调用方处理。

            throws 有如下使用规则:

            • 1.如果方法中全部是非检查异常(即 ErrorRuntimeException 以及的子类),那么可以不使用 throws 关键字来声明要抛出的异常,编译器能够通过编译,但在运行时会被系统抛出;
            • 2.如果方法中可能出现检查异常,就必须使用 throws 声明将其抛出或使用 try catch 捕获异常,否则将导致编译错误;
            • 3.当一个方法抛出了异常,那么该方法的调用者必须处理或者重新抛出该异常;
            • 4.当子类重写父类抛出异常的方法时,声明的异常必须是父类所声明异常的同类或子类。

            5. 捕获异常

            使用 try 和 catch 关键字可以捕获异常。try catch 代码块放在异常可能发生的地方。它的语法如下:

            Tips:
            idea里可以通过//ctrl+alt+t选择代码自动包裹

            
            try {
                // 可能会发生异常的代码块
            } catch (Exception e1) {
                // 捕获并处理try抛出的异常类型Exception
            } catch (Exception2 e2) {
                // 捕获并处理try抛出的异常类型Exception2
            } finally {
                // 无论是否发生异常,都将执行的代码块
            }
            

            我们来看一下上面语法中的 3 种语句块:

            1. try 语句块:用于监听异常,当发生异常时,异常就会被抛出;
            2. catch 语句块catch 语句包含要捕获的异常类型的声明,当 try 语句块发生异常时,catch 语句块就会被检查。当 catch 块尝试捕获异常时,是按照 catch 块的声明顺序从上往下寻找的,一旦匹配,就不会再向下执行。因此,如果同一个 try 块下的多个 catch 异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面;
            3. finally 语句块:无论是否发生异常,都会执行 finally 语句块。finally 常用于这样的场景:由于 finally 语句块总是会被执行,所以那些在 try 代码块中打开的,并且必须回收的物理资源(如数据库连接、网络连接和文件),一般会放在 finally 语句块中释放资源。

            try 语句块后可以接零个或多个 catch 语句块,如果没有 catch 块,则必须跟一个 finally 语句块。简单来说,try 不允许单独使用,必须和 catchfinally 组合使用,catchfinally 也不能单独使用。

            实例如下:

            
            package com.caq.exception;
            
            public class Demo01 {
                //打印a/b的结果
                public static void test(int a,int b){
            
                    System.out.println(a/b);
                }
            
                public static void main(String[] args) {
                    //调用test方法
                    try {
                        test(5,0);
                    }catch (ArithmeticException e1){
                        System.out.println("捕获的异常为:"+e1);
                    }finally {
                        System.out.println("无论是否发送异常,我都会执行哦~");
                    }
            
                }
            }
            

            运行结果:

            
            捕获的异常为:java.lang.ArithmeticException: / by zero
            无论是否发送异常,我都会执行哦~
            

            test() 方法中除数 b0,会发生除零异常,我们在方法调用处使用了 try 语句块对异常进行捕获;如果捕获到了异常, catch 语句块会对 ArithmeticException 类型的异常进行处理,此处打印了一行自定义的提示语句;

            最后的 finally 语句块,无论发生异常与否,总会执行。

            Java 7 以后,catch 多种异常时,也可以像下面这样简化代码:

            
            try {
                // 可能会发生异常的代码块
            } catch (Exception | Exception2 e) {
                // 捕获并处理try抛出的异常类型
            } finally {
                // 无论是否发生异常,都将执行的代码块
            }
            
            

            6. 自定义异常

            自定义异常,就是定义一个类,去继承 Throwable 类或者它的子类。

            Java 内置了丰富的异常类,通常使用这些内置异常类,就可以描述我们在编码时出现的大部分异常情况。一旦内置异常无法满足我们的业务要求,就可以通过自定义异常描述特定业务产生的异常类型。

            实例:

            
            public class ExceptionDemo4 {
            
                static class MyCustomException extends RuntimeException {
                    
                    public MyCustomException() {
                        super("我的自定义异常");
                    }
                }
            
                public static void main(String[] args) {
                  	// 直接抛出异常
                    throw new MyCustomException();
                }
            }
            

            运行结果:

            
            Exception in thread "main" ExceptionDemo4$MyCustomException: 我的自定义异常
            	at ExceptionDemo4.main(ExceptionDemo4.java:13)
            

            在代码中写了一个自定义异常 MyCustomException,继承自 RuntimeException,它是一个静态内部类,这样在主方法中就可以直接抛出这个异常类了。当然,也可以使用 catch 来捕获此类型异常。

            7. 异常链

            异常链是以一个异常对象为参数构造新的异常对象新的异常对象将包含先前异常的信息。简单来说,就是将异常信息从底层传递给上层,逐层抛出,我们来看一个实例:

            
            public class ExceptionDemo5 {
            
                
                static class FirstCustomException extends Exception {
            
                    // 无参构造方法
                    public FirstCustomException() {
                        super("第一个异常");
                    }
                }
            
                
                static class SecondCustomException extends Exception {
            
                    public SecondCustomException() {
                        super("第二个异常");
                    }
                }
            
                
                static class ThirdCustomException extends Exception {
            
                    public ThirdCustomException() {
                        super("第三个异常");
                    }
                }
            
                
                public static void f1() throws FirstCustomException {
                    throw new FirstCustomException();
                }
            
                
                public static void f2() throws SecondCustomException {
                    try {
                        f1();
                    } catch (FirstCustomException e) {
                        throw new SecondCustomException();
                    }
                }
            
                
                public static void f3() throws ThirdCustomException {
                    try {
                        f2();
                    } catch (SecondCustomException e) {
                        throw new ThirdCustomException();
                    }
                }
            
                public static void main(String[] args) throws ThirdCustomException {
                    // 调用静态方法f3()
                    f3();
                }
            }
            

            运行结果:

            
            Exception in thread "main" ExceptionDemo5$ThirdCustomException: 第三个异常
            	at ExceptionDemo5.f3(ExceptionDemo5.java:46)
            	at ExceptionDemo5.main(ExceptionDemo5.java:51)
            

            通过运行结果,我们只获取到了静态方法 f3() 所抛出的异常堆栈信息,前面代码所抛出的异常并没有被显示。

            我们改写上面的代码,让异常信息以链条的方式 “连接” 起来。可以通过改写自定义异常的构造方法,来获取到之前异常的信息。实例如下:

            
            public class ExceptionDemo6 {
            
                
                static class FirstException extends Exception {
            
                    // 无参构造方法
                    public FirstException() {
                        super("第一个异常");
                    }
            
                }
            
                
                static class SecondCustomException extends Exception {
            
                    
                    public SecondCustomException(Throwable cause) {
                        super("第二个异常", cause);
                    }
                }
            
                
                static class ThirdCustomException extends Exception {
            
                    
                    public ThirdCustomException(Throwable cause) {
                        super("第三个异常", cause);
                    }
                }
            
                
                public static void f1() throws FirstException {
                    throw new FirstException();
                }
            
                
                public static void f2() throws SecondCustomException {
                    try {
                        f1();
                    } catch (FirstException e) {
                        throw new SecondCustomException(e);
                    }
                }
            
                
                public static void f3() throws ThirdCustomException {
                    try {
                        f2();
                    } catch (SecondCustomException e) {
                        throw new ThirdCustomException(e);
                    }
                }
            
                public static void main(String[] args) throws ThirdCustomException {
                    // 调用静态方法f3()
                    f3();
                }
            }
            

            运行结果:

            
            Exception in thread "main" ExceptionDemo6$ThirdCustomException: 第三个异常
            	at ExceptionDemo6.f3(ExceptionDemo6.java:74)
            	at ExceptionDemo6.main(ExceptionDemo6.java:80)
            Caused by: ExceptionDemo6$SecondCustomException: 第二个异常
            	at ExceptionDemo6.f2(ExceptionDemo6.java:62)
            	at ExceptionDemo6.f3(ExceptionDemo6.java:72)
            	... 1 more
            Caused by: ExceptionDemo6$FirstException: 第一个异常
            	at ExceptionDemo6.f1(ExceptionDemo6.java:51)
            	at ExceptionDemo6.f2(ExceptionDemo6.java:60)
            	... 2 more
            

            通过运行结果,我们看到,异常发生的整个过程都打印到了屏幕上,这就是一个异常链。

            8. 小结

            通过学习,我们知道了异常就是程序上的错误,良好的异常处理可以提高代码的健壮性。

            Java 语言中所有错误(Error)和异常(Exception)的父类都是 Throwable

            ErrorExceptionThrowable 的直接子类,我们通常说的异常处理实际上就是处理 Exception 及其子类,异常又分为检查型异常非检查型异常

            通过抛出异常和捕获异常来实现异常处理。我们亦可以通过继承 Throwable 类或者它的子类来自定义异常类。通过构造方法获取之前异常的信息可以实现异常链

            以上就是全面了解java中的异常处理的详细内容,更多关于java异常处理的资料请关注编程界其它相关文章!

            --结束END--

            本文标题: 全面了解java中的异常处理

            本文链接: https://lsjlt.com/news/69.html(转载时请注明来源链接)

            有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

            猜你喜欢
            • 全面了解java中的异常处理
              目录Java 异常处理1. 什么是异常2. Java 异常类架构2.1 Throwable 类2.2 Error 类2.3 Exception 类3. 如何进行异常处理4. 抛出异常4.1 实例4.2 throw4.3 throws5. 捕...
              99+
              2020-09-26
              java 异常处理
            • 全面了解java异常
              目录异常的概念异常体系异常的分类异常产生的过程分析异常的处理抛出异常throw声明异常throws捕获异常try…catch捕获异常语法如何获取异常信息:finally代码块try ...
              99+
              2024-04-02
            • 带你全面认识Java中的异常处理
              目录Java异常处理异常体系的介绍常见运行时异常常见编译时异常补充:自定义异常总结 Java异常处理 异常体系的介绍 什么事异常处理 异常是程序在“编译&rdq...
              99+
              2022-12-26
              java中异常处理的机制 java中怎么处理异常 JAVA中异常处理的定义
            • Java中的异常处理机制介绍(非常全面!)
              目录异常处理机制编译时异常处理机制异常处理方式一异常处理方式二异常处理方式三运行时异常处理机制总结异常处理机制 异常的默认处理流程如下: 默认会在出现异常的代码那里自动的创建一个异常...
              99+
              2023-01-18
              Java异常处理机制原理 java中包含异常处理机制 java异常处理方式两种
            • PHP 异常处理:对错误和异常的全面处理
              异常处理是 php 中处理错误和异常的重要机制,提高了应用程序的健壮性和稳定性。错误由解释器抛出,表示无法恢复的严重问题。异常由代码抛出,表示可恢复的运行时问题。php 提供了 erro...
              99+
              2024-05-11
              php 异常处理
            • SpringBoot全局异常处理 | Java
              ⭐简单说两句⭐ 作者:后端小知识 CSDN个人主页:后端小知识 🔎GZH:后端小知识 🎉欢迎关注🔎点赞👍收藏⭐️留言...
              99+
              2023-10-12
              java spring boot 后端
            • Java Springboot全局异常处理
              目录前言一、思路?二、步骤1.自定义接口:2.自定义错误枚举3.自定义异常类4.异常捕获5.在代码中抛异常总结前言 对于作为菜鸟程序员的我来说,经常在controller使用try-...
              99+
              2024-04-02
            • JAVA异常与异常处理详解
              一、异常简介什么是异常?异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域的情况,称之为异常。java中异常的体系是怎么样的呢?(推荐:java视频教程)Java中的所有不正常类都继承于Throwable类...
              99+
              2020-06-12
              JAVA
            • 新手了解java 异常处理基础知识
              目录一、异常体系结构1.什么是异常2.异常的体系结构二、异常处理throw 与 throws三、自定义异常运行时异常编译时异常总结一、异常体系结构 1.什么是异常 在java程序运行...
              99+
              2024-04-02
            • 深入了解C++异常处理
              目录基本的异常处理怎么抛出异常捕获和处理异常不存在异常的描述 --- 标识性作用    删减符 ...异常处理中的传参操作  --- 可以写一个变量进去可以抛出自己类的对象标准库当中...
              99+
              2024-04-02
            • springboot全局异常处理详解
              一、单个controller范围的异常处理package com.xxx.secondboot.web;import org.springframework.web.bind.annotation.ExceptionHandler;impo...
              99+
              2023-05-31
              spring boot 全局异常
            • Java异常处理深入理解
              目录图片解析:异常的处理:处理机制一:try-catch-finallyfinally的再说明:处理机制二:throws + 异常类型开发中应该如何选择两种处理方式?如何自定义异常类...
              99+
              2024-04-02
            • Java编程中的异常处理
              本篇内容介绍了“Java编程中的异常处理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java编程中的异常处理是一个很常见的话题了,几乎任何...
              99+
              2023-06-17
            • 怎么处理Java中的异常
              这篇文章主要讲解了“怎么处理Java中的异常”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么处理Java中的异常”吧!异常与error介绍下面还是先让我们来看一下基本概念吧! 异...
              99+
              2023-06-16
            • Java中如何实现Springboot全局异常处理
              这篇文章主要为大家展示了“Java中如何实现Springboot全局异常处理”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中如何实现Springboot全局异常处理”这篇文章吧。一、思路...
              99+
              2023-06-25
            • Java中的异常你了解多少?
              目录 一.认识异常二.异常分类三.异常的分类1.编译时异常2.运行时异常 四.异常的处理1.LYBL:事前防御型2.EAFP:事后认错型 五.异常的抛出Throw==注意事项== 六.异常的捕获1.异常的捕获2.异常声明...
              99+
              2023-12-22
              java python 开发语言
            • Java中如何处理异常
              这篇文章主要为大家展示了“Java中如何处理异常”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中如何处理异常”这篇文章吧。 在Finally中清理资源或者使用Try-With-Resou...
              99+
              2023-06-02
            • java异常:异常处理--try-catch结构详解
              目录总结 从键盘接收两个整数,输出两数的商: package java_exception; import java.util.Scanner; public clas...
              99+
              2024-04-02
            • Java JSP 异常处理:处理错误和异常
              异常处理在 Java 和 JSP 编程中至关重要,因为它允许应用程序优雅地处理错误和异常情况,从而提高健壮性和用户体验。 JSP 中的异常处理 JSP 提供了三种主要机制来处理异常: page 指令:该指令指定处理某个页面上所有未处理异...
              99+
              2024-03-15
              JSP
            • Java 详解异常的处理机制
              目录1.异常概述与异常体系结构1.1异常概述1.2运行时异常与编译时异常1.3异常体系结构2.常见异常1.ArrayIndexOutOfBoundsException2.NullPo...
              99+
              2024-04-02
            软考高级职称资格查询
            编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
            • 官方手机版

            • 微信公众号

            • 商务合作