Marvel-Site Marvel-Site
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)

Marvel

吾必当乘此羽葆盖车
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)
  • Java

    • Java基础

      • Java基本概念与常识
      • Java基本语法
      • Java基本数据类型
      • Java包装类
      • Java基本概念对比辨析
      • Java面向对象基础
      • Java异常处理
        • 异常类的层次结构
          • 检查性异常
          • 运行时异常
          • 错误
        • Throwable 类常用方法
        • 异常捕获 try-catch-finally
          • try-catch-finally执行顺序
          • return与finally
        • 语法糖 try-with-resources
        • 关键字 throws/throw
        • 常见问题
      • Java注解
      • Java泛型
      • Java反射
      • Java函数式编程
    • Java进阶

    • Java容器

    • Java并发编程

    • Java虚拟机

    • 常见面试题

  • 计算机基础

  • 框架|中间件

  • 架构

  • 后端
  • Java
  • Java基础
Marvel
2022-07-13
目录

Java异常处理

# Java异常处理

# 异常类的层次结构

image-20220718142200371

在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类:

  • 异常 Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获
    • 检查性异常 Checked Exception :必须处理
    • 运行时异常 Runtime Exception :可以不处理
  • 错误 Error :属于程序无法处理的错误。

# 检查性异常

Java 代码在编译过程中,如果受检查异常没有被 catch/throw 处理的话,就没办法通过编译 。

Checked Exception

此时运行程序

java: 未报告的异常错误java.lang.InterruptedException; 必须对其进行捕获或声明以便抛出
1

# 运行时异常

Java 代码在编译过程中 ,我们即使不处理运行时异常也可以正常通过编译。

RuntimeException 及其子类都统称为运行时异常,例如:

  • NullPointerException:空指针异常

  • NumberFormatException:字符串转换为数字异常

  • ArrayIndexOutOfBoundsException:数组越界

  • ClassCastException:类型转换错误

  • ArithmeticException:算术错误

  • ConcurrentModificationException:并发修改异常

# 错误

错误不是异常,而是脱离程序员控制的问题,它们在编译期间检查不到的,当错误发生程序会立刻停止。

「错误」不是「异常」,但是我们经常把「错误」称为「异常」,比如OOM异常,其实指的是OOM错误。

常见错误有:

  • java.lang.OutOfMemoryError:内存溢出错误
  • java.lang.StackOverflowError:栈溢出错误

# Throwable 类常用方法

  • String getMessage(): 返回异常发生时的简要描述
  • String toString(): 返回异常发生时的详细信息
  • String getLocalizedMessage(): 返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • void printStackTrace(): 在控制台上打印 Throwable 对象封装的异常信息

# 异常捕获 try-catch-finally

  • try块: 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
  • catch块: 用于处理 try 捕获到的异常,可以有多个 catch 块,每个块用于捕获不同的异常。
  • finally 块: 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

# try-catch-finally执行顺序

示例:

try {
    System.out.println("Try to do something");
    throw new RuntimeException("RuntimeException");
} catch (Exception e) {
    System.out.println("Catch Exception -> " + e.getMessage());
} finally {
    System.out.println("Finally");
}
1
2
3
4
5
6
7
8

输出:

Try to do something
Catch Exception -> RuntimeException
Finally
1
2
3

# return与finally

  1. 当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。
  2. 不要在 finally 语句块中使用 return!当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句会被忽略。这是因为 try 语句中的 return 返回值会先被暂存在一个本地变量中,当执行到 finally 语句中的 return 之后,这个本地变量的值就变为了 finally 语句中的 return 返回值。
  3. 在特殊情况下 finally 中的代码不会被执行,就比如说 finally 之前虚拟机被终止运行的话,finally 中的代码就不会被执行。

// TODO:从字节码理解执行顺序

# 语法糖 try-with-resources

JDK7 之后,Java 新增的 try-with-resource 语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 。

try (resource declaration) {
  // 使用的资源
} catch (ExceptionType e1) {
  // 异常块
}
1
2
3
4
5

示例:

import java.io.*;

public class RunoobTest {

    public static void main(String[] args) {
    String line;
        try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 关键字 throws/throw

⭐ throws:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁。

public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}
1
2
3
4
5
6
7
8
9

⭐ throw:用来抛出一个具体的异常类型

public class Test {
    public static void main(String[] args) {
        User user1 = new User("admin", "123");
        User user2 = null;
        login(user1);
        login(user2);
    }

    public static void login(User user) {
        if (user == null) {
            // 这里可以通过继承RuntimeException来自定义异常
            throw new RuntimeException("传入用户参数异常");
        }
        System.out.println("登录成功!");
    }
}
class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

控制台输出


 



登录成功!
Exception in thread "main" java.lang.RuntimeException: 传入用户参数异常
	at test.Test.login(Test.java:25)
	at test.Test.main(Test.java:20)
1
2
3
4

catch 块捕获异常,自定义抛出异常。

# 常见问题

⭐ return 同时出现在 try 和 finally 中

public class Test {
    public int method() {
        int a = 0;
        try {
            a = 1;
            return a;
        } finally {
            a = 2;
            return a;
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test.method());  // 2
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
    public int method() {
        try {
            return 1;
        } finally {
            return 2;
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test.method()); // 2
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
编辑 (opens new window)
#Java
上次更新: 2023/08/20, 21:21:52
Java面向对象基础
Java注解

← Java面向对象基础 Java注解→

最近更新
01
位运算
05-21
02
二叉树
05-12
03
Spring三级缓存解决循环依赖
03-25
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Marvel
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式