【Java基础】——深入理解Java异常

news2024/9/20 20:23:35

目录

  • 1- 什么是异常概述(What、Why)
    • 1-1 什么是异常(What)
    • 1-2 为什么要有异常处理机制(Why)
  • 2- ⭐异常体系结构图-总览
    • 2-1 分类
    • 2-2 异常体系结构小结
  • 3- 五大运行时异常
    • 3-1 NullPointerException 空指针异常
    • 3-2 ArithmeticException 算数异常
    • 3-3 ArrayIndexOutOfBoundsException 数组下标越界异常
    • 3-4 ClassCastException 异常
    • 3-5 NumberFormatException 数字格式不正确异常
  • 4- 编译异常
  • 5- 异常处理机制
    • 5-1 try-catch-finally 的处理机制
      • try-catch 细节
    • 5-2 throws 异常处理机制
      • thorws 基本介绍
      • throws 细节
    • 5-3 throw 和 throws 的区别
  • 6- 自定义异常
    • 6-1 自定义异常步骤
  • 小结
      • 1- 什么是异常?Java 中的异常是如何分类的?
      • 2- 常见的 Exception 有哪些?
      • 3- throw 和 throws 有什么区别?
      • 4- Error 和 Exception 有什么区别?
      • 5- try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
      • 6- finally 一定会被执行吗?
      • 7- 什么是受检异常(Checked Exception)和非受检异常(Unchecked Exception)?
      • 8- 解释 try-catch-finally 语句的工作原理。
      • 9- 三道异常处理经典题目,如果 try 中带有 return,finally 怎么执行?

1- 什么是异常概述(What、Why)

1-1 什么是异常(What)

基本概念

  • 在 Java 语言中,将程序执行中发生的不正常的情况称为 “异常”。(开发过程中的语法错误和逻辑错误不是异常)

执行过程中的异常可以分为两类

  • Error(错误):Java 虚拟机无法解决的严重问题。比如 JVM 系统内部错误、资源耗尽等情况。比如:StackOverflowError(栈溢出)和 OOM(out of memory),Error 是严重的错误,程序会崩溃。
  • Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等。
    • Exception分为两大类:运行时异常(程序运行时,发生的异常)和 编译时异常(编译时,编译器检查出来的异常)。

通过一个例子,引出异常

public class Exception1 {

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;
        // 执行到这部分的时候,程序会不出现(抛出异常) ArithmeticException
        // 当抛出异常之后,程序就退出崩溃了,下面的代码就不再执行
        int res = num1/num2;
        System.out.println("程序继续运行...");
    }
}

  • 针对上述问题,执行到 int res = num1/num2;代码的时候,会出现异常。
  • 问题在于出现了一个不算致命的问题,但会导致整个系统崩溃。因此 Java 设计者提供了 异常处理机制来解决这个问题。

1-2 为什么要有异常处理机制(Why)

  • 如果程序员任务一段代码可能出现异常/问题,可以使用 try-catch 异常处理机制来解决。从而保证代码的健壮性。如果进行了异常处理,即使出现了异常,程序可以继续执行。
  • 常见的异常处理机制如下:
public class Exception1 {

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;

        try{
            int res = num1/num2;
        }catch (Exception e){
//            e.printStackTrace();
            System.out.println(e.getMessage()); // 输出异常信息
        }

        System.out.println("程序继续运行...");
    }
}

2- ⭐异常体系结构图-总览

2-1 分类

  • 下图的内容需要记忆

  • 编译异常(Checked 受检异常):是在 Java源程序 经过 javac.exe 转为字节码文件阶段遇到的异常。
  • 运行异常(Unchecked 非受检异常):是在字节码文件在内存中加载、运行时类的时候出现的异常。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2-2 异常体系结构小结

异常分为两大类,运行时异常和编译时异常:

  • 运行时异常(Unchecked 非受检异常):编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
    • 举例:(比如除法操作,nums1 = 10nums2 = 0nums1/nums2 可得到运行时异常)
  • 编译时异常(Checked 受检异常):是在 Java源程序 经过 javac.exe 转为字节码文件阶段遇到的异常。
// 编译时异常举例 
public class Exception02 {
    public static void main(String[] args) {
        // Throwable
        FileInputStream fis;
        try {
            fis = new FileInputStream("d:\\aa.jpg");
            int len;
            while ((len = fis.read()) != -1) {
                System.out.println(len);
            }
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 在上述代码中,FileInputStream会报编译时异常,也就是 IDEA 工具会报错,必须立即处理的异常。

3- 五大运行时异常

常见的运行时异常包括

  • NullPointerException :空指针异常
  • ArithmeticException:数学运算异常
  • ArrayIndexOutOfBoundsException:数组下标越界异常
  • ClassCastException:类型转换异常
  • NumberFormatException:数字格式不正确异常

3-1 NullPointerException 空指针异常

NullPointerException 空指针异常

  • 当应用程序试图在需要对象的地方使用 null 时,抛出该异常,看案例演示。
public class NullPointerException_ {
    public static void main(String[] args) {
        String name = null;
        // 在输出的时候会报空指针异常
        System.out.println(name.length()); 
    }
}

3-2 ArithmeticException 算数异常

  • 比如出现 除以 0 的操作的时候就会出现算数异常
public class Exception1 {

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;
        // 执行到这部分的时候,程序会不出现(抛出异常) ArithmeticException
        // 当抛出异常之后,程序就退出崩溃了,下面的代码就不再执行
        int res = num1/num2;
        System.out.println("程序继续运行...");
    }
}

3-3 ArrayIndexOutOfBoundsException 数组下标越界异常

  • 用非法的索引访问数组时候抛出的异常。如果索引为负数或者大于等于数组大小,则该索引非法。
public class Exception1 {

    public static void main(String[] args) {
        int[] nums = new int[4];
        System.out.println(nums[4]);
    }
}

3-4 ClassCastException 异常

  • 当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,以下代码将生成一个 ClassCastException
public class ClassCastException_ {
    public static void main(String[] args) {
        A b = new B(); // 向上转型
        B b2 = (B)b; // 向下转型,这里是OK
        C c2 = (C)b; // 这里抛出ClassCastException
    }
}

class A {}
class B extends A {}
class C extends A {}

3-5 NumberFormatException 数字格式不正确异常

  • 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常 => 使用异常我们可以确保输入是满足条件数字。
  • 例如在使用 Integer.parseInt("你好") 的时候,本来是想将字符串中的数字转为整型,但这个时候就会出现数字格式不正确的异常。
public class NumberFormatException_ {
    public static void main(String[] args) {
        String name = "你好呀";
        // 将String 转成 int
        int num = Integer.parseInt(name); // 抛出NumberFormatException
        System.out.println(num); // 
    }
}

4- 编译异常

  • 编译异常是指,在编译期间就必须处理的异常,否则代码不能通过编译。编译异常常常发生在操作网络、文件、数据库的时候。

常见的编译时异常

  • SQLException:操作数据库时候,查询表可能发生的异常
  • IOException:操作文件时候发生的异常
  • FileNotFoundException:当操作一个不存在的文件时,发生异常
  • ClassNotFoundException:加载类,而文件不存在时,异常
  • EOFException:操作文件,到文件末尾发生异常
  • IllegalArgumentException:参数异常

5- 异常处理机制

异常处理机制就是在发生异常时,对异常处理的方式,主要有两种:

  • try-catch-finally
    • 程序员在代码中捕获发生的异常,自行处理
  • throws
    • 将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是 JVM

5-1 try-catch-finally 的处理机制

try-catch-finally 机制:

  • try 中锁放的代码是有可能出现异常的代码,catch 主要是负责捕获异常。
  • 当异常发生的时候,系统将异常封装给 Exception 的对象 e,传递给 catch,当 catch 得到异常对象之后,我们需要自己处理,如果没有发生异常的话 catch 中的代码是不会执行的。
  • finally中的代码部分,无论是否有异常发生,始终是要执行 finally 代码快的(例如对资源释放的代码一般是放在 finally中)
  • 如果没有 finally 也是允许的
try{
    // 有可能有异常的代码
}catch(Exception e){
    // 捕获到异常
    // 1. 当异常发生时
    // 2. 系统将异常封装给 Exception 的对象 e,传递给 catch
    // 3. 得到异常对象之后,程序员自己处理
    // 4. 注意,如果没有发生异常 catch 中的代码块不执行
}finally{
    // 不管 try 中的代码块是否有异常发生,始终要执行 finally 代码块
    // 通常将资源释放的代码,放在 finally 中
}

try-catch 细节

:::info

  • 1) 如果异常发生了,则异常后面的代码不会执行,直接进入到 catch 块
  • 2) 如果异常没有发生,则顺序执行 try 中代码,不会进入到 catch 中
  • 3) 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用 -finally
  • 4) 可以有多个 catch 语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception 在后,NullPointerException 在前),如果发生异常,只会匹配一个catch,案例演示
  • 5) 可以进行 try-finally 配合使用,这种方法相当于没有捕获异常,因此程序会直接崩掉。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
  • 6) 如果在 catch 代码块中有一个临时变量 i,进行了 ++ 操作之后直接 return,此时不会直接返回会等到 finally 的代码执行完成之后才会返回。且 返回的 catch中临时变量结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

:::

1) 如果异常发生了,则异常后面的代码不会执行,直接进入到 catch 块

  • 以下代码块中 System.out.println("数字: " + a); 部分的内容是不会输出的
public class TryCatchDetail {
    public static void main(String[] args) {
        try {
            String str = "你好";
            int a = Integer.parseInt(str);
            System.out.println("数字: " + a);
        } catch (NumberFormatException e) {
            System.out.println("异常信息=" + e.getMessage());
        }
    }
}

2) 如果异常没有发生,则顺序执行 try 中代码,不会进入到 catch 中

3) 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用 -finally

4) 可以有多个 catch 语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(**Exception**** 在后,**NullPointerException** 在前),如果发生异常,只会匹配一个catch,案例演示**

  • 如以下代码,其中 Person 对象有一个空指针异常,和一个算数异常。此时异常的排序需将子类排在前,父类排在后面。
public class TryCatchDetail02 {
    public static void main(String[] args) {
        try {
            Person person = new Person();
            person = null;
            System.out.println(person.toString()); // NullPointerException
            int n1 = 10;
            int n2 = 0;
            int res = n1 / n2; // ArithmeticException
        } catch (NullPointerException e) {
            System.out.println("空指针异常=" + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("算术异常=" + e.getMessage());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            System.out.println("finally代码块被执行");
        }
    }
}

class Person {
    private String name = "jack";

    public String getName(){
        return name;
    }
}

5) 可以进行 try-finally 配合使用,这种方法相当于没有捕获异常,因此程序会直接崩掉。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑


5-2 throws 异常处理机制

JVM 处理异常的机制是,直接输出异常信息 ——> 中断(退出)这个程序

  • 在 Java 中如果对于非受检异常,也就是运行时异常,如果没有显示使用 try-catch 进行异常捕获,此时默认方法会带一个 throws Exception

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

thorws 基本介绍

  • 1)如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理
  • 2)在方法声明中用 throws 语句可以声明抛出异常的列表,throws 后面常类型可以是方法中产生的异常类型,也可以是它的父类。
public class Throws01 {
    public static void main(String[] args) {
    }

    public void f2() throws FileNotFoundException {
        // 创建了一个文件流对象
        // 老韩解读:
        // 1. 这里的异常是一个FileNotFoundException 编译异常
        // 2. 使用前面讲过的 try-catch-finally
        // 3. 使用throws,抛出异常,让调用f2方法的调用者(方法)处理
        FileInputStream fis = new FileInputStream("d:/aa.txt");
    }
}

throws 细节

:::info
throws 抛出异常介绍

  • 1) 对于编译异常,程序必须处理,比如 try-catch 或者 throws
  • 2) 对于运行时异常,程序如果没有处理,则默认的就是 throws 方式处理
  • 3) 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型
  • 4) 在throws过程中,如果有方法try-catch,就相当于处理异常,就可以不必 throws

:::


1) 对于编译异常,程序必须处理,比如 try-catch 或者 throws

2) 对于运行时异常,程序如果没有处理,则默认的就是 throws 方式处理

3) 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型

class Father { // 父类
    public void method() throws RuntimeException {
    }
}

class Son extends Father { // 子类
    // 3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,
    // 所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型
    @Override
    public void method() throws NullPointerException {
    }
}

5-3 throw 和 throws 的区别

  • thorws 后面跟的是一个具体的异常类型
  • throw 后面跟的是一个具体的异常对象


6- 自定义异常

基本概念

  • 当程序中出现了某些“错误”,但该错误信息并没有在 Throwable 子类中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。

6-1 自定义异常步骤

  • 1)定义类:自定义异常类名(程序员自己写)继承 Exception 或 RuntimeException
  • 2)如果继承 Exception ,属于编译异常
  • 3)如果继承 RuntimeException ,属于运行异常(一般来说,继承 RuntimeException)

举例

  • 当我们接收 Person 对象年龄时,要求范围在 18-120 之间,否则抛出一个自定义异常(要求继承RuntimeException),并给出提示信息。

:::info
自定义异常

  • 一般是继承 **RuntimeException** 类,之后通过构造器方法实现自定义异常的信息

:::

public class CustomException {
    public static void main(String[] args) {
        int age = 80;
        // 要求范围在 18 - 120 之间,否则抛出一个自定义异常
        if (!(age >= 18 && age <= 120)) {
            // 通过构造器设置自定义异常信息
            throw new AgeException("年龄需要在 18~120之间");
        }
        System.out.println("你的年龄范围正确。");
    }
}

// 自定义一个异常
class AgeException extends RuntimeException {
    public AgeException(String message) { // 构造器
        super(message);
    }
}

小结

1- 什么是异常?Java 中的异常是如何分类的?

Java基础异常

分析

  • Java异常
  • 思路:Throwable接口有两个子类,分别是 Error 和 Exception。
  • 关键字:Throwable

知识点详解

  • Java中的异常都来自一个接口 Throwable,其中有两个主要的子类。

1- 谈论 Throwable、Exception、Error 三者的关系

  • 一个是 Exception、一个是 Error
    • Error 一般是虚拟机异常,是程序无法干预的一种错误,这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。常见的有 StackOverFlowOutOfMemory
    • Exception 是 Java 的一个异常类,Exception 下的异常主要分为两类,运行时异常和编译时异常。

2- 谈论 Exception 下的分类

Exception类下的异常主要分为两类

  • 运行时异常(Unchecked 非受检异常):编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。java.lang.RuntimeException 类及它的子类都是运行时异常对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
    • 举例:(比如除法操作,nums1 = 10nums2 = 0nums1/nums2 可得到运行时异常)
  • 编译时异常(Checked 受检异常):是在 Java源程序 经过 javac.exe 转为字节码文件阶段遇到的异常。

回答

:::info
Java中的异常主要都来自于一个 Throwable 接口

  • ①介绍 Error 和 Exception:Throwable 接口下主要有两个类,分别是 Error 和 Exception
    • **Error** 指的是虚拟机异常,是程序无法干预的一种错误。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。常见的有 StackOverFlowOutOfMemory
    • **Exception** 异常是程序本身可以捕获并处理的异常。
  • ② Exception 异常分类,主要分为两种
    • 运行时异常(Unchecked 非受检异常):运行时异常,一般是在 Java 运行的过程中由于编程的逻辑错误而导致的异常,是可以手动处理避免的。java.lang.RuntimeException 类及它的子类都是运行时异常对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
    • 编译时异常(Checked 受检异常):是在 Java源程序 经过 javac.exe 转为字节码文件阶段遇到的异常。这类异常常见的就是在我们写代码过程中 IDEA 会给出的提示,也就是 Java 程序在运行前需要解决的异常,不然 Java 程序不能编译执行。

常见的运行时异常

  • NullPointerException :空指针异常
  • ArithmeticException:数学运算异常
  • ArrayIndexOutOfBoundsException:数组下标越界异常
  • ClassCastException:类型转换异常
  • NumberFormatException:数字格式不正确异常

常见的编译时异常

  • SQLException:操作数据库时候,查询表可能发生的异常
  • IOException:操作文件时候发生的异常
  • FileNotFoundException:当操作一个不存在的文件时,发生异常
  • ClassNotFoundException:加载类,而文件不存在时,异常
  • EOFException:操作文件,到文件末尾发生异常
  • IllegalArgumentException:参数异常

:::


2- 常见的 Exception 有哪些?

Java基础异常

分析

  • Java异常

知识点详解

程序本事可以捕获并且处理的异常就是 Exception 异常,Exception 又分为两类,一种是运行时异常一种是编译时异常

运行时异常

  • 都是 RuntimeException 类及其子类异常,如 NullPointerException (空指针异常)、IndexOutBoundsException(下标越界异常)等,这些异常不是受检异常,程序可以选择捕获处理也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
  • 运行时异常的特点是 Java 编译器不回去检查它,也就是说,当程序中出现这类异常,即使没有用 try-catch 捕获,也没有使用 throws 语句抛出它,也会编译通过。

非运行时异常(编译异常)

  • RuntimeException以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、SQLException 等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

回答

:::info
其中 **Exception** 异常又划分为 编译时异常和运行时异常两种

  • 运行时异常:也就是 **RutimeException** 下的异常,这种异常可以通过 throws 或者 try-catch 的方式手动处理,这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。常见的异常有 NullPointerException (空指针异常)、IndexOutBoundsException(下标越界异常)等。
  • **非运行时异常(编译异常):**也就是 **RutimeException** 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 **IOException****SQLException** 等以及用户自定义的**Exception**异常,一般情况下不自定义检查异常。

常见的运行时异常

  • NullPointerException :空指针异常
  • ArithmeticException:数学运算异常
  • ArrayIndexOutOfBoundsException:数组下标越界异常
  • ClassCastException:类型转换异常
  • NumberFormatException:数字格式不正确异常

常见的编译时异常

  • SQLException:操作数据库时候,查询表可能发生的异常
  • IOException:操作文件时候发生的异常
  • FileNotFoundException:当操作一个不存在的文件时,发生异常
  • ClassNotFoundException:加载类,而文件不存在时,异常
  • EOFException:操作文件,到文件末尾发生异常
  • IllegalArgumentException:参数异常

:::


3- throw 和 throws 有什么区别?

Java基础异常

分析

  • Java异常

知识点详解

  • thorws 后面跟的是一个具体的异常类型
  • throw 后面跟的是一个具体的异常对象


回答

:::info

  • throw:用于抛出一个具体的异常对象。
  • throws:后面跟的是一个具体的异常类型,用于声明该方法可能抛出的异常。子类方法抛出的异常范围更小,或者根本不抛出异常。

:::


4- Error 和 Exception 有什么区别?

Java基础异常

分析

  • Java异常

知识点详解

  • **Error**:JVM 无法解决的严重问题,如栈溢出 StackOverflowError、内存溢出 OOM 等。程序无法处理的错误。
  • **Exception**:其他因为编程错误或偶然的外在因素导致的一般性问题,可以在代码中进行处理。如:空指针异常、数组下标越界等。

回答

:::info

  • **Error**:JVM 无法解决的严重问题,如栈溢出 StackOverflowError、内存溢出 OOM 等。程序无法处理的错误。
  • **Exception**:其他因为编程错误或偶然的外在因素导致的一般性问题,可以在代码中进行处理。如:空指针异常、数组下标越界等。

:::


5- try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

Java基础异常

分析

  • Java异常

知识点详解

  • 会,当 try 和 catch 中有 return 时,finally 仍然会执行。

回答

:::info

  • 会,当 try 和 catch 中有 return 时,finally 仍然会执行。

:::


6- finally 一定会被执行吗?

Java基础异常

**分析 **

  • Java异常

知识点详解

不一定,有以下两种情况 finally 不会被执行:

  • ① 程序未执行到 try 代码块,(比如在执行 finally 之前程序就 exit 退出了)
try {
    System.out.println("Try to do something");
    throw new RuntimeException("RuntimeException");
} catch (Exception e) {
    System.out.println("Catch Exception -> " + e.getMessage());
    // 终止当前正在运行的Java虚拟机
    System.exit(1);
} finally {
    System.out.println("Finally");
}
  • ② 当一个线程在执行 try 语句块或者 catch 语句块时被打断(Interrupted)或者被终止(Killed),与其相对应的 finally 语句块可能不会执行。还有更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。

回答

:::info
不一定,有以下两种情况 finally 不会被执行:

  • ① 程序未执行到 try 代码块,(比如在执行 finally 之前程序就 exit 退出了)
  • ② 当一个线程在执行 try 语句块或者 catch 语句块时被打断(Interrupted)或者被终止(Killed),与其相对应的 finally 语句块可能不会执行。还有更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。

:::


7- 什么是受检异常(Checked Exception)和非受检异常(Unchecked Exception)?

Java基础异常

**分析 **

  • Java异常

知识点详解

其中 **Exception** 异常又划分为 编译时异常和运行时异常两种

  • 运行时异常(非受检异常):也就是 **RutimeException** 下的异常,这种异常可以通过 throws 或者 try-catch 的方式手动处理,这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。常见的异常有 NullPointerException (空指针异常)、IndexOutBoundsException(下标越界异常)等。
  • **非运行时异常(受检异常):**也就是 **RutimeException** 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 **IOException****SQLException** 等以及用户自定义的**Exception**异常,一般情况下不自定义检查异常。

回答

:::info
其中 **Exception** 异常又划分为 编译时异常和运行时异常两种

  • 运行时异常(非受检异常):也就是 **RutimeException** 下的异常,这种异常可以通过 throws 或者 try-catch 的方式手动处理,这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。常见的异常有 NullPointerException (空指针异常)、IndexOutBoundsException(下标越界异常)等。
  • **非运行时异常(受检异常):**也就是 **RutimeException** 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 **IOException****SQLException** 等以及用户自定义的**Exception**异常,一般情况下不自定义检查异常。

:::


8- 解释 try-catch-finally 语句的工作原理。

Java基础异常

**分析 **

  • Java异常

知识点详解

try 部分的代码

  • 其中 try 中放的代码是可能出现异常的代码块。catch 主要是负责捕获异常。

catch部分

  • 如果 try 部分的代码发生了异常,catch 就负责捕获信息,将异常封装为 Exception 对象。当 catch 得到异常对象之后,我们需要自己处理,如果没有发生异常的话 catch 中的代码是不会执行的。

finally部分

  • finally中的代码部分,无论是否有异常发生,始终是要执行 finally 代码快的(例如对资源释放的代码一般是放在 finally中)如果没有 finally 也是允许的。

try-cath细节

  • 1) 如果异常发生了,则异常后面的代码不会执行,直接进入到 catch 块
  • 2) 如果异常没有发生,则顺序执行 try 中代码,不会进入到 catch 中
  • 3) 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用 -finally
  • 4) 可以有多个 catch 语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception 在后,NullPointerException 在前),如果发生异常,只会匹配一个catch,案例演示
  • 5) 可以进行 try-finally 配合使用,这种方法相当于没有捕获异常,因此程序会直接崩掉。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
  • 6) 如果在 catch 代码块中有一个临时变量 i,进行了 ++ 操作之后直接 return,此时不会直接返回会等到 finally 的代码执行完成之后才会返回。且 返回的 catch中临时变量结果。

回答

:::info
try 部分的代码

  • 其中 try 中放的代码是可能出现异常的代码块。catch 主要是负责捕获异常。

catch部分

  • 如果 try 部分的代码发生了异常,catch 就负责捕获信息,将异常封装为 Exception 对象。当 catch 得到异常对象之后,我们需要自己处理,如果没有发生异常的话 catch 中的代码是不会执行的。

finally部分

  • finally中的代码部分,无论是否有异常发生,始终是要执行 finally 代码快的(例如对资源释放的代码一般是放在 finally中)如果没有 finally 也是允许的。

try-cath细节

  • 1) 如果异常发生了,则异常后面的代码不会执行,直接进入到 catch 块
  • 2) 如果异常没有发生,则顺序执行 try 中代码,不会进入到 catch 中
  • 3) 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用 -finally
  • 4) 可以有多个 catch 语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception 在后,NullPointerException 在前),如果发生异常,只会匹配一个catch,案例演示
  • 5) 可以进行 try-finally 配合使用,这种方法相当于没有捕获异常,因此程序会直接崩掉。应用场景,就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑
  • 6) 如果在 catch 代码块中有一个临时变量 i,进行了 ++ 操作之后直接 return,此时不会直接返回会等到 finally 的代码执行完成之后才会返回。且 返回的 catch中临时变量结果。

:::


9- 三道异常处理经典题目,如果 try 中带有 return,finally 怎么执行?

Java基础异常

**分析 **

  • Java异常

知识点详解

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test());
    }

    public static int test() {
        try {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.print("3");
        }
    }
}
  • 执行结果:31
  • 解析:trycatchfinally 的基础用法,在 return 前会先执行 finally 的语句块,所以是先输出 finally 里面的 3,再输出1。
public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }

    public static int test1() {
        try {
            return 2;
        } finally {
            return 3;
        }
    }
}
  • 执行结果:3
  • 解析:try 返回前先执行 finally,如果 finally 里面不按套路出牌,直接 return 了,自然也就不会走到 try 里面的 return了。
public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }

    public static int test1() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 3;
        }
    }
}
  • 执行结果:2
  • 解析:这段不应该返回 3 吗,其实在实际执行 finally 之前, JVM 会先将 i 的结果暂存起来,然后 finally 执行完成之后,会返回之前存储的结果,而不是返回 i ,所以 i 已经被修改为 3,最终返回的还是之前暂存的结果 2。

回答

:::info

  • 解析:trycatchfinally 的基础用法,在 return 前会先执行 finally 的语句块,所以是先输出 finally 里面的 3,再输出1。

:::

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HPL 源码结构分析

文件夹结构&#xff1a; $ cd /home/hipper/ex_hpl_hpcg/ $ pwd $ mkdir ./openmpi $mkdir ./openblas $mkdir ./hpl $ tree 1. 安装openmpi 1.1.1 使用Makefile下载配置编译安装 openmpi Makefile&#xff1a; all:wget https://download.open-mpi.org/release/open-m…

java spring定时任务-动态任务

cron表达式 在线生成https://cron.qqe2.com/ 6个时间刻度的话 * * * * * * 分别对应 秒 分 时 日 月 星期 &#xff1b; 7个时间刻度的话 * * * * * * * 分别对应 秒 分 时 日 月 星期 年&#xff1b;每隔5秒执行一次&#xff1a;*/5 * * * * ? 每隔1分钟执行一次&#xff1a…

AI如何辅助未来数学研究:陶哲轩的最新见解与应用展望

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;AI在多个领域的应用已经渗透到了我们生活的方方面面。然而&#xff0c;在严谨且逻辑性极强的数学研究领域&#xff0c;AI能否真正发挥作用&#xff1f;2024年&#xff0c;著名数学家、菲尔兹奖得主陶哲轩在IM…

【Nacos】配置中心

Nacos除了注册中心和负载均衡之外&#xff0c;还是一个配置中心&#xff0c;具备配置管理的功能。 Nacos 配置中心是一种用于集中式管理应用程序配置的服务&#xff0c;它可以将应用程序的配置从代码和本地配置文件中分离出来&#xff0c;实现配置的集中管理和动态更新。通过 …

刘润《关键跃升》读书笔记7

沟通&#xff1a; 想明⽩&#xff0c;说清楚&#xff0c;能接受 团队沟通的正确⽅式可以⽤9个字来概括&#xff1a;想明⽩&#xff0c;说清楚&#xff0c;能接受 &#xff08;⻅图4-1&#xff09;想明⽩ 有时经理跟⼈沟通&#xff0c;讲完之后却⽆奈地对员⼯说&#xff0c;你怎…

远程访问电脑共享文件

远程访问电脑共享文件&#xff0c;可以通过多种方法实现&#xff0c;每种方法都有其特点和适用场景。以下是一些常见的方法及其步骤&#xff1a; 一、使用Microsoft远程桌面 启用远程桌面&#xff1a; 在目标电脑上&#xff0c;打开“开始”菜单&#xff0c;选择“设置”>“…

常见概念 -- WDM/OTN 时延

什么是时延&#xff1f; 在通信网络中&#xff0c;时延指原始数据经一台转发设备的编码等一系列处理过程后由发送端发送&#xff0c;通过传输链路传输&#xff0c;到达另一台&#xff08;目的地&#xff09;设备的接收端并解码还原为原始数据所花费的时间。网络时延主要由以下几…

多维时序 | Matlab基于TCN-Transformer+LSTM双输入神经网络时间序列预测

多维时序 | Matlab基于TCN-TransformerLSTM双输入神经网络时间序列预测 目录 多维时序 | Matlab基于TCN-TransformerLSTM双输入神经网络时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-TransformerLSTM双输入神经网络时间序列预测&#xff…

基于SpringBoot的校园自助洗衣服务管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的校园自助洗衣服务…

SAP Fiori-Vscode 环境搭建中npm报错

文章目录 前提&#xff1a; vscode 安装好了&#xff0c;node 配置完毕&#xff0c;npm环境搭建OK新建一个Fiori 初始化初始化性项目的报错&警告Q1: npm WARN config global --global, --local are deprecated. Use --locationglobal insteadQ2: npm打包出现警告&#xff0…

GPU池化赋能智能制造

2023年3月10日&#xff0c;“第六届智能工厂高峰论坛”在杭州隆重揭幕。本次会议由e-works数字化企业网、浙江制信科技有限公司主办&#xff0c;中国人工智能学会智能制造专业委员会、长三角新能源汽车产业链联盟、长三角(杭州)制造业数字化能力中心、浙江省智能工厂操作系统技…

基于微信小程序的宠物之家的设计与实现

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的宠物之家/宠物综合…

Redis复习笔记整理(2w+)

目录 1、Redis简介 1.1 补充数据类型Stream 1.2 Redis底层数据结构 1.3 Redis为什么快 1.4 持久化机制* 1.4.1 RDB持久化 bgsave执行流程 如何保证数据一致性 快照操作期间服务崩溃 RDB优缺点 1.4.2 AOF持久化 为什么采用写后日志 如何实现AOF 什么是AOF重写 AO…

vue项目中引入组件时出现的Module is not installed问题

在Vue项目中&#xff0c;如果遇到了如图“Module is not installed”这样的错误&#xff0c;通常这 个错误并不是直接由Vue或Vue CLI本身抛出的&#xff0c;而是可能因为几个不同的原因导致的。 这个错误可能是在你尝试引入一个模块或组件时&#xff0c;该模块或组件并没有被正…

java基础 | 动态代理

动态代理 简而言之就是&#xff1a;首先创建一套动态代理的规则&#xff0c;创建好自己的接口&#xff0c;和实现类&#xff0c;在调用时直接调用&#xff08;缺少什么参数&#xff0c;补充哪个参数&#xff01;&#xff09; 实现步骤&#xff1a; 设计动态代理的规则&#x…

Windows系统下编译C++源码并调用

现在很多的C库都以源码的形式在github网站开源&#xff0c;如果要使用&#xff0c;可以直接下载到本地&#xff0c;添加到工程中调用。也可以将源码编译为动态或静态库文件&#xff0c;然后将库文件添加到工程中。 在这里我们将GoogleTest源码编译&#xff0c;然后加到工程中。…

OpenGL(三)着色器语言GLSL

着色器语言 在GPU上运行的图形渲染语言&#xff0c;类C风格。 类似于CUDA&#xff0c;但是又没有CUDA通用&#xff0c;又有点像Verilog这种硬件描述语言 GLSL是一种着色器语言&#xff0c;需要有对应的图形API环境配合&#xff0c;可以使用OpenGL&#xff0c;也可以使用OpenGL…

Proteus仿真综合实例(1)

分享一些基于Proteus的仿真实例&#xff0c;供大家学习参考。 1、51单片机230个Proteus仿真实例 包含基于51单片机的230个仿真实例&#xff0c;涉及定时器、中断、LCD显示、DS18B20温度测量、DS1621温度测量、PWM生成等充足电路模型案例。 2、51交通灯 模拟实现基于51单片机…

音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件

在文章《音视频入门基础&#xff1a;PCM专题&#xff08;1&#xff09;——使用FFmpeg命令生成PCM音频文件并播放》中讲述了生成PCM文件的方法。通过FFmpeg命令可以把该PCM文件转为AAC裸流文件&#xff1a; ./ffmpeg -f s16le -ar 44100 -ac 2 -i audio1.pcm audio1.aac 由于…

《论层次架构及其在软件系统中的应用》写作框架,软考高级系统架构设计师

论文真题 层次架构作为软件系统设计的一种基本模式&#xff0c;对于实现系统的模块化、可维护性和可扩展性具有至关重要的作用。在软件系统的构建过程中&#xff0c;采用层次架构不仅可以使系统结构更加清晰&#xff0c;还有助于提高开发效率和质量。因此&#xff0c;对层次架…