tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础与面向对象

    • Java中的一些概念
    • Java中的数组
    • String类跟关键字final
    • Java 日期时间与Date
    • Java中的异常处理
      • 分类
        • Checked Exception(受检异常)
        • Unchecked Exception(非受检异常)
        • Error(错误)
        • 关系
      • 如何处理
        • 一个问题
        • try、catch。finally 的基础用法
        • 第一个总结:
        • 第二个总结:
        • 第三个总结:
        • try-catch会影响性能吗
    • Java枚举
    • Java序列化和反序列化
    • Java中的注解
    • Java中的IO流
    • Java中抽象类与接口
  • 高级进阶

  • 并发合集

  • JVM合集

  • 实战与细节

  • 代码之丑与提升

  • 《Java》学习笔记
  • Java基础与面向对象
EffectTang
2023-10-30
目录

Java中的异常处理

# Java中的异常处理

在 Java 中,异常(Exception)是程序执行过程中发生的意外情况或错误条件。Java 提供了丰富的异常处理机制来帮助开发者捕获和处理这些异常,以确保程序的健壮性和可靠性。根据不同的特性,Java 中的异常可以分为以下几类:

# 分类

# Checked Exception(受检异常)

受检异常定义:这类异常是由编译器检查的异常。如果方法中可能会抛出这种类型的异常,那么该方法必须声明它会抛出这个异常,或者在其内部使用 try-catch 块来处理这个异常。

此外,受检异常指的都是不受程序直接控制的错误。它们通常都是由于与外部资源/网络交互而发生的,例如数据库问题、网络连接错误、文件丢失等问题,比如:IOException、SQLException、ClassNotFoundException、ParseException

这种异常有以下几个特点:

  • 编译时检查。
  • 必须显式处理。
  • 包括所有继承自 Exception 类但不继承自 RuntimeException 的类。

那有了所谓的受检异常有————非受检异常吗?答案是有的。

# Unchecked Exception(非受检异常)

非受检定义:这类异常不是由编译器检查的异常。它们通常是由于编程错误引起的,如空指针引用、数组越界等。这类异常不需要强制处理,但通常建议进行适当的处理,以提高程序的健壮性。

这种异常有以下几个特点:

  • 运行时检查。
  • 不需要显式处理。
  • 包括所有继承自 RuntimeException 的类。

# Error(错误)

最后还有一种,它其实不是异常,而是错误。

它的定义:Error 是用于表示 JVM 自身的问题或其他严重问题的对象。这些问题通常是不可恢复的,例如内存不足、JVM 内部错误等。因此,一般情况下我们不会尝试去捕获或处理 Error 类型的异常。

它有以下几个特点:

  • 表示严重的系统级问题。
  • 大多数情况下不应被应用程序捕获。

发生错误时,通常不应该捕获 Error,而是应该让程序终止,并考虑从外部解决问题,如增加内存、优化代码等。

# 关系

Java异常机制的核心是Throwable类,所有的异常和错误都是这个类的子类。Throwable类有两个重要的子类:Exception(异常)和Error(错误)。

Exception(异常):是程序可以处理的异常,通常是由程序中的错误引起的,比如数组越界、类型转换错误等。异常又可以分为受查异常(checked exception)和非受查异常(unchecked exception)。

# 如何处理

对于程序中的异常如何处理呢?通常有2种方式,

  • 捕获-然后处理
  • 抛出

# 一个问题

对于异常可以一直抛出,不处理吗?就传递到了最终调用者,main方法中,也只是抛出,不对其进行处理?

  • 技术上是可以的,但程序最终会报错

从技术角度讲,Java 编译器允许你将受检异常一路向上抛,直到最顶层方法(例如 main 方法),并且这些方法也可以声明抛出这些异常。当程序运行时遇到未捕获的受检异常,JVM 会打印堆栈跟踪信息并终止程序。

所以对于抛出的异常我们应该进行处理或者延迟处理,否则它将结束你的程序。这样一来就可以避免以下错误:

  1. 用户体验:直接让异常导致程序终止,并打印堆栈跟踪信息,可能会给用户带来困惑,尤其是当用户不是开发人员时。良好的错误处理应该提供更友好的错误信息或采取适当的恢复措施。
  2. 健壮性:不处理异常意味着你的程序可能无法优雅地应对错误情况,从而影响其健壮性和可靠性。例如,在服务器应用程序中,你不希望一个未捕获的异常导致整个服务崩溃。

# try、catch。finally 的基础用法

# 第一个总结:

在 return 前会先执行 finally 语句块,

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");
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

所以是先输出finally里的3,再输出return的1,所以结果为 31

# 第二个总结:

try返回前 先执行 finally

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        try {
            return 2;
        } finally {
            return 3;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

try返回前先执行 finally,结果finally里不按套路出牌,直接 return了,自然也就走不到 try里面的 return了。输出结果为:3

# 第三个总结:

在执行finally之前,JVM会将i的结果暂存起来

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;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

【解析】在执行finally之前,JVM会将i的结果暂存起来,然后finally执行完毕后,会返回之前暂存的结果,而不是返回i,所以即使i已经被修改为3,最终返回的还是之前暂存的结果2

# try-catch会影响性能吗

如果不发生异常,则不会。

虽然在字节码层面生成了对应的字节码,但没发生异常,并不会去执行。所以不发生异常,不会影响性能。如果发生了,则会执行多余的字节码,相应的会降低性能。

上次更新: 2025/04/23, 16:23:16
Java 日期时间与Date
Java枚举

← Java 日期时间与Date Java枚举→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式