N

Norlcayn的博客

A text-focused Halo theme

  • 首页
  • 文章
  • 默认分类
  • 关于
主页 Java异常处理
文章

Java异常处理

发表于 2026-01-15 更新于 昨天
作者 Administrator
18~24 分钟 阅读

异常的介绍和体系结构

异常介绍

  • 指的是程序在编译或执行过程中,出现的非正常的情况(错误)
  • ArrayIndexOutOfBoundsException:索引越界异常
  • ClassCaseException:类型转换异常
  • NullPointerException:空指针异常
  • 注意:语法错误,不是异常

异常体系

Java中所有的异常和错误的父类是Throwable,它的两个子类为Error和Exception

Error:

  • 严重级别问题
  • 常见的有栈内存溢出(StackOverflowError),堆内存溢出(OutOfMemoryError)

Exception:

  • RuntimeException及其子类:运行时异常
  • 数组索引越界异常、空指针异常、类型转换异常都属于运行时异常
  • 编译阶段没有错误,运行时可能会出现错误。这种错误通常都是程序员代码不严谨造成的
  • 除RuntimeException之外的所有异常:编译时异常
  • 编译阶段就出现的错误。主要起到提醒作用

异常的默认处理流程

示例:

package com.norlcyan.exception;

public class ExceptionDemo01 {
    /*
        异常默认的处理方式:向上抛出
    */
    public static void main(String[] args) {
        System.out.println("main start...");
        method();           // ③ main方法接收到异常对象,继续向上抛出 new ArithmeticException();
                            // ④ JVM虚拟机接收到异常对象,将异常的错误信息打印在控制台,将程序停止
        System.out.println("main end...");
    }

    private static void method() {
        System.out.println("method start...");
        int i = 1 / 0;      // ① 会在出现异常的位置,创建一个异常对象 new ArithmeticException();
                            // ② 将异常对象向上抛出,抛给main方法
        System.out.println("method end...");
    }
}

处理流程图:

  sequenceDiagram    participant JVM    participant Main as main方法    participant Method as method方法        JVM->>Main: 程序开始执行    Main->>Main: 打印 "main start..."    Main->>Method: 调用method()方法    Method->>Method: 打印 "method start..."    Method->>Method: 执行 int i = 1/0    Note right of Method: 发生算术异常    Method-->>Method: 创建ArithmeticException对象    Method-->>Main: 抛出异常对象    Note right of Main: 接收到异常    Main-->>JVM: 继续向上抛出异常    Note right of JVM: JVM接收到异常    JVM->>JVM: 打印异常信息    JVM->>JVM: 终止程序执行

异常处理方式

try…catch

  • 能够抛出的异常对象捕获,然后执行异常的处理方案
  • 好处:程序不会直接停止,而是执行异常的处理方案、
  • 格式:

try { 可能会出现异常的代码 } catch (异常类型1 变量) { 处理异常的方案 } - 示例:

public class ExceptionDemo02 { public static void main(String[] args) { System.out.println("开始"); try { int i = 1 / 0; } catch (ArithmeticException e) { System.out.println("[" + e + "] 捕获了异常..."); System.out.println("异常原因:" + e.getMessage()); e.printStackTrace(); // 输出详细异常信息,不会中断程序执行 } System.out.println("结束"); } }

异常的所有方法都在父类Throwable中实现了,并且只需要记住两个方法

getMessage:获取到发生异常的原因

printStackTrace:输出详细异常信息,不会中断程序异常

当异常对象不匹配catch中的类型时,是不会执行异常处理方案的。当需要捕获多种异常时,可以创建多个catch语句或使用异常类型分隔符:

try {
    int[] arr = null;
    System.out.println(arr[10]);
} catch (ArithmeticException e) {
    System.out.println(e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println(e.getMessage());
} catch (NullPointerException e) {
    System.out.println(e.getMessage());
}

// 也可以简写成:
try {
    int[] arr = null;
    System.out.println(arr[10]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException | NullPointerException e) {
    System.out.println(e.getMessage());
}

当使用异常类型分隔符时,最终编译的字节码文件中会转换为多个catch

如果异常类型为Exception(所有异常的父类),那么要在最后catch,使用异常类型分隔符也必须只能是兄弟类型

throws抛出

  • throws:用在方法上,作用是声明,声明这个方法中的异常是抛出处理
  • 格式:public void method() throws 异常1, 异常2, 异常3 ... {}

示例:

import java.io.FileNotFoundException;
import java.io.FileReader;

public class ExceptionDemo05 {
    public static void main(String[] args) throws Exception {
        method();
    }

    public static void method() throws FileNotFoundException, ClassNotFoundException {
        System.out.println("开始");
        FileReader fr = new FileReader("D:\\abc.txt");
        System.out.println("结束");

        Class.forName("com.norlcyan.exception.Student");
    }
}

// 在继承关系中,子类重写父类方法,不能抛出父类中不存在的,或者比父类更大的异常
class Fu {
    public void show() throws Exception {
        System.out.println("Fu...Show...");
    }
}

class Zi extends Fu{
    @Override
    public void show() throws FileNotFoundException, ClassNotFoundException {
        FileReader fr = new FileReader("D:\\abc.txt");
        Class.forName("com.norlcyan.exception.Student");
    }
}

当某个方法抛出了异常,那调用这个方法的方法也需要抛出异常,且类型大小不能低于(>=)被调用方法的异常

当某个子类中重写后的成员方法抛出了异常,那它的父类也方法也需要抛出异常,且子类异常类型不能大于(<=)父类异常

throw关键字

这是用于抛出异常的关键字,使用方式就是throw new Exception(...),理解为抛出创建的异常对象

比如,当创建学生对象时,需要对年龄进行负数判断:

public void setAge(int age) throws Exception {
if (age >= 0 && age <= 100) {
this.age = age;
} else {
throw new Exception("年龄有误...");
}
}

try…catch…和throws

使用思路:当问题需要暴露给开发者时,优先使用throws。需要将问题捕获,且不影响程序运行,就选择try…catch

自定义异常

创建自定义异常,可以更加精准的捕获异常

自定义异常分类:

  1. 自定义编译时异常: - 定义一个异常类继承Exception - 重写构造器
  2. 自定义运行时异常: - 定义一个异常类继承RuntimeException - 重写构造方法

示例:

public class StudentAgeException extends Exception{
    public StudentAgeException() {
    }

    public StudentAgeException(String message) {
        super(message);
    }
}

抛出异常

public void setAge(int age) throws StudentAgeException {
    ...;
    throw new StudentAgeException("...")
}

捕获异常

try {
...
} catch (StudentAgeException e) {
...
}

编译时异常(检查异常)- 必须声明throws

运行时异常(非检查异常)- 不需要声明throws

自定义异常的选择

场景 异常类型 是否需要throws
业务逻辑异常 Exception ✅ 必须声明
可恢复异常 Exception ✅ 必须声明
外部资源异常 Exception ✅ 必须声明
编程错误 RuntimeException ❌ 不需要声明
系统错误 RuntimeException ❌ 不需要声明
违反契约 RuntimeException ❌ 不需要声明
Java
Java语法 Java异常处理 自定义异常
许可协议:  CC BY 4.0
分享

相关文章

1月 15, 2026

Java异常处理

异常的介绍和体系结构 异常介绍 指的是程序在编译或执行过程中,出现的非正常的情况(错误) ArrayIndexOutOfBoundsException:索引越界异常 ClassCaseException:类型转换异常 NullPointerException:空指针异常 注意:语法错误,不是异常 异

1月 15, 2026

Java网络编程

网络编程概念 可以让设备中的程序与网络上其他设备中的程序进行数据交互的技术(实现网络通信) 基本的通信架构分为两种:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端) 无论是CS架构还是BS架构,都必须依赖网络编程 Java中提供了java.ne

1月 15, 2026

Java面向对象编程

面向对象介绍 面向对象:并不是一个技术,而是一种编程的指导思想 以什么形式组织代码,以什么思路解决问题 为什么要学习面向对象? 因为生活中,我们要解决问题时,就是采用这种指导思想去解决的 所以,我们写程序去解决问题时,如果也能采用这种指导思想 就会使编程变得非常简单,程序也便于理解 面向对象,重点学

下一篇

Linux项目部署

上一篇

Java网络编程

最近更新

  • Hello Halo
  • 状态机
  • 数据表设计规范
  • 缓存优化
  • 事务失效

热门标签

Halo 异常处理 Redisson 并行 Vue 并发 递归 请求限流 SpringAMQP 类加载器

目录

©2026 Norlcayn的博客. 保留部分权利。

使用 Halo 主题 Chirpy