☰
Java异常的详细介绍
2026/10/30 1:51:34 网站建设 项目流程

大家在写 Java 代码时,是不是经常被各种红色报错搞得头大? 空指针、数组越界、除零错误…… 这些都是程序里的异常。 异常处理是 Java 开发最基础、最常用、面试最高频的知识点之一。 今天这篇文章,我就带大家从 0 到 1 彻底搞懂 Java异常:概念、体系、处理、流程、自定义异常,一篇全搞定!

一、什么是异常?

简单一句话:
程序运行过程中发生的不正常行为,就叫异常。
就像人会生病一样,代码写得再严谨,也可能因为数据错误、网络问题、资源不足而出问题。
Java 中常见的异常我们几乎都遇到过:

// 1. 算术异常:除零错误System.out.println(10/0);
// 2. 数组越界异常int[]arr={1,2,3};System.out.println(arr[100]);
// 3. 空指针异常int[]arr=null;System.out.println(arr.length);

每种异常,Java 都用一个异常类来描述,方便我们定位、处理。

二、Java 异常体系结构

Java 异常有一套非常清晰的继承体系,顶层父类是 Throwable。

Throwable├─Error(错误:JVM严重问题,无法处理) └─Exception(异常:可捕获处理,开发重点)
  1. Throwable
    所有异常、错误的顶级父类。
  2. Error(错误)
    JVM 自己都解决不了的严重问题,程序员无法通过 try-catch 处理。

典型代表:

StackOverflowError:栈溢出OutOfMemoryError:内存溢出

遇到 Error,只能改代码逻辑,没有别的办法。
3. Exception(异常)
我们平时说的 “异常”,就是它!
可以通过代码捕获处理,让程序继续运行。

三、异常的两大分类

按发生时机,异常分为两大类:编译时异常 和 运行时异常。

  1. 编译时异常(受检异常 Checked Exception)
    编译期间就报错,不处理无法运行
    必须显式捕获 或 声明抛出
例子:FileNotFoundException、IOException、CloneNotSupportedException
// 编译直接报错:必须处理 CloneNotSupportedException@OverridepublicPersonclone(){return(Person)super.clone();}
  1. 运行时异常(非受检异常 Unchecked Exception)
    RuntimeException 及其子类
    编译不报错,运行时才会触发
例子:NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException

小提醒:
拼写错误、语法错误不是异常,是编译错误!

四、异常处理核心思想

处理异常有两种编程思想:

1.(事前检查) 先判断,再操作。正常代码和错误代码混在一起,结构混乱。

2.(先操作,出错再处理) 先执行业务代码,遇到异常再捕获处理。 正常流程与异常流程分离,代码更清晰。

Java 异常处理的核心思想就是:(先操作,出错再处理)
Java 异常 5 大关键字:throw、try、catch、finally、throws

五、异常的抛出:throw

主动手动抛出异常,把错误信息告诉调用者。

thrownew异常类("异常提示信息");示例:获取数组元素并校验publicstaticintgetElement(int[]array,intindex){if(array==null){thrownewNullPointerException("数组不能为 null");}if(index<0||index>=array.length){thrownewArrayIndexOutOfBoundsException("数组下标越界");}returnarray[index];}

throw 注意事项

  1. 必须写在方法内部
  2. 只能抛出 Exception 或其子类对象
  3. 运行时异常可不用处理,编译时异常必须处理
  4. 异常抛出后,后续代码不再执行

六、异常的捕获与处理

  1. 异常声明:throws
    方法自己不处理异常,甩锅给调用者。
修饰符 返回值类型 方法名(参数列表)throws异常1,异常2...{}

示例

publicvoidopenConfig(Stringfilename)throwsFileNotFoundException{if(!filename.equals("config.ini")){thrownewFileNotFoundException("配置文件名称错误");}}

throws 要点

  1. 跟在方法参数列表之后
  2. 可声明多个异常,有父子关系只需要写父类
  3. 调用者必须处理,或继续 throws

真正捕获:try-catch-finally
自己处理异常,让程序不崩溃。

try{// 可能出现异常的代码}catch(异常类型 e){// 捕获并处理异常}finally{// 无论是否异常,一定会执行}

示例

publicstaticvoidmain(String[]args){try{int[]arr={1,2,3};System.out.println(arr[100]);}catch(ArrayIndexOutOfBoundsExceptione){e.printStackTrace();// 打印完整异常栈}System.out.println("程序继续执行~");}

catch 捕获规则
按异常类型匹配捕获
多个异常:多个 catch 或 使用 并且 合并
子类异常在前,父类异常在后,否则编译报错
不推荐直接 catch (Exception),会吞掉异常
必须执行:finally
无论是否异常、是否 return,finally 一定执行!

publicstaticintfunc(){try{return10;}finally{return20;}}

// 输出结果:20
开发规范:绝对不要在 finally 里写 return!

七、异常处理流程

1.异常不是停在当前方法,而是向上传递:
2.本方法出现异常 → 寻找本层 catch
3.没有匹配 catch → 抛给调用方法
4.一直到 main 方法都没处理 → 交给 JVM → 程序终止

八、自定义异常

Java 内置异常不能满足所有业务场景,我们可以自己定义异常。
自定义步骤
继承 Exception(受检)或 RuntimeException(非受检)
实现带 String 参数的构造方法

// 受检异常classUserNameExceptionextendsException{publicUserNameException(Stringmessage){super(message);}}
// 非受检异常classPasswordExceptionextendsRuntimeException{publicPasswordException(Stringmessage){super(message);}}

使用示例

publicstaticvoidlogin(StringuserName,Stringpassword)throwsUserNameException{if(!"admin".equals(userName)){thrownewUserNameException("用户名错误");}System.out.println("登录成功");}

核心速记
throw: 方法内,手动抛一个异常
throws: 方法上,声明异常类型
try: 放可能异常的代码
catch: 捕获处理
finally: 一定执行,关闭资源

throw vs throws的比较
throw 方法内抛对象;throws 方法声明异常。

总结

异常体系:Throwable → Error / Exception
两类异常:编译时(必须处理)、运行时(可不处理)
处理流程:throw 抛出 → throws 声明 → try-catch-finally 捕获
自定义异常:继承 Exception/RuntimeException 即可

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询