云计算百科
云计算领域专业知识百科平台

java异常详解:为0基础小白专门打造,帮助你学会异常处理!

目录

一、先搞懂:异常到底是什么?(大白话解释)

二、Java 异常的两大分类(核心!记清这两类就够了)

1. 运行时异常(非检查型异常)—— 最常见,可处理可不处理

核心特点

常见例子(记这 5 个,覆盖 80% 开发场景)

2. 编译时异常(检查型异常)—— 编译器强制要求处理,不处理编译报错

核心特点

常见例子(记这 3 个,覆盖开发常用场景)

两类异常核心对比(一张表记牢)

三、异常处理的 3 个核心关键字 ——try、catch、finally(零基础必学)

核心思想

基础语法模板(死记硬背,直接套用)

关键规则(零基础必看,避免踩坑)

入门示例 1:处理运行时异常(除以 0,ArithmeticException)

入门示例 2:多 catch 块(处理多种不同异常)

入门示例 3:finally 的核心作用 —— 释放资源(必用场景)

四、处理编译时异常的 2 种方式(编译器强制要求,二选一)

方式 1:try-catch-finally 捕获处理(推荐,主动处理异常)

示例:处理控制台输入的 IOException(编译时异常)

方式 2:throws 声明异常(甩锅,把异常交给上层处理)

示例:main 方法 throws 声明 IOException,甩锅给 JVM

两种方式对比(零基础怎么选?)

五、2 个进阶关键字:throw(主动抛异常)、throws(声明异常)

1. throw —— 手动 / 主动抛出一个异常(方法内部用)

作用

语法

示例:主动抛出非法参数异常(IllegalArgumentException,运行时异常)

2. throws —— 声明方法可能抛出的异常(方法名后面用)

作用

示例:方法内 throw 异常,方法名后 throws 声明

throw 和 throws 核心区别(一张表分清,不混淆)

六、零基础异常处理的 5 个黄金原则(避坑必备,直接套用)

原则 1:局部变量必须初始化,避免 “未初始化” 导致的异常

原则 2:调用对象的方法 / 属性前,先判空(避免空指针)

原则 3:资源使用后必须关闭,且关闭前要判空

原则 4:catch 块要针对性处理,不要只写一个 Exception

原则 5:运行时异常尽量处理,编译时异常必须处理

七、零基础快速上手总结(核心知识点浓缩,一分钟回顾)


本文专为 Java 零基础小白打造,用通俗的语言、直白的例子讲清异常是什么、异常有哪些、怎么处理异常、如何主动抛异常,全程避开复杂术语,学完就能上手写异常处理代码,轻松搞定 Java 异常核心知识点!

一、先搞懂:异常到底是什么?(大白话解释)

你写的 Java 代码,编译没报错,但运行时突然崩了 / 出问题,这种运行时的错误 / 意外情况,就是 Java 中的异常。

  • 比如:用一个数除以 0(int a = 10 / 0;)、访问数组时下标越界(int[] arr = {1,2}; arr[5] = 3;)、读取文件时文件不存在,这些都会触发异常。
  • 没有异常处理时,程序会直接终止运行,并在控制台打印一堆红色的错误信息,体验极差;有了异常处理,我们可以捕获错误、优雅处理,让程序继续运行,还能给用户友好提示。

简单类比:你出门逛街(程序运行),突然下雨了(异常)—— 没准备的话会被淋成落汤鸡(程序终止);带了伞(异常处理),就能正常继续逛街(程序运行)。

二、Java 异常的两大分类(核心!记清这两类就够了)

Java 把所有异常分成两大阵营,处理规则完全不同,零基础先记清这两类的区别,不用记复杂的继承关系,记住「特点 + 例子 + 处理方式」即可。

1. 运行时异常(非检查型异常)—— 最常见,可处理可不处理

核心特点
  • 编译时不强制要求处理,编译器不会报错,写代码时不用管也能编译通过;
  • 错误通常是程序员写代码的疏忽导致(比如粗心写了除以 0、下标越界);
  • 运行时才会触发,触发后若未处理,程序直接终止。
常见例子(记这 5 个,覆盖 80% 开发场景)
异常名称触发场景大白话解释
ArithmeticException 整数除以 0(10/0) 数学运算错误
ArrayIndexOutOfBoundsException 数组下标超出范围(arr[5],数组只有 3 个元素) 数组下标越界
NullPointerException 调用 null 对象的方法 / 属性(String s = null; s.length();) 空指针(对象没创建就用)
InputMismatchException Scanner 读取数据类型不匹配(用nextInt()读了字母) 输入的类型不对
ClassCastException 错误的类型转换(Object o = "abc"; int a = (int)o;) 类型强转失败

2. 编译时异常(检查型异常)—— 编译器强制要求处理,不处理编译报错

核心特点
  • 编译时必须手动处理,否则代码连编译都通不过(编译器直接标红);
  • 错误通常是程序外部的客观原因导致,不是程序员粗心(比如要读的文件被删了、网络断了);
  • 属于 “可预见的意外”,Java 强制要求程序员提前做处理(比如文件不存在要提示,不能让程序直接崩)。
常见例子(记这 3 个,覆盖开发常用场景)
异常名称触发场景大白话解释
IOException 文件读取 / 写入、控制台输入输出异常 IO 操作(文件 / 流)错误
FileNotFoundException 读取文件时,文件不存在 文件没找到
SQLException 连接数据库、操作数据库表失败 数据库操作错误

两类异常核心对比(一张表记牢)

对比维度运行时异常(非检查型)编译时异常(检查型)
编译要求 不强制处理,编译不报错 必须处理,不处理编译报错
触发原因 程序员代码疏忽(主观) 程序外部客观原因(客观)
处理优先级 建议处理,避免程序运行崩 必须处理,否则代码无法运行
常见触发阶段 运行时 编译时检查,运行时触发

三、异常处理的 3 个核心关键字 ——try、catch、finally(零基础必学)

这是 Java 处理异常的基础核心语法,也是最常用的方式,作用是「捕获异常→处理异常→保证收尾操作执行」,三者配合使用,语法固定,背会模板直接套就行。

核心思想

把可能触发异常的代码放进try块,把异常发生后的处理逻辑放进catch块,把无论是否发生异常都必须执行的收尾代码放进finally块(比如关闭文件、关闭 Scanner)。

基础语法模板

try {
// 第一步:放【可能触发异常】的代码
// 比如:除以0、Scanner读取、文件读取等
可能出问题的代码;
} catch (异常类型 异常变量名) {
// 第二步:捕获指定类型的异常,发生时执行这里的代码
// 比如:打印错误信息、给用户提示、重新赋值等
异常处理逻辑; // 如System.out.println("出错了!");
} finally {
// 第三步:无论是否发生异常,这里的代码【一定执行】
// 作用:收尾操作(关闭资源、释放内存)
必须执行的收尾代码; // 如sc.close();、关闭文件流等
}

关键规则(零基础必看,避免踩坑)

  • try块不能单独存在,必须跟catch、finally至少一个配合(try-catch / try-finally / try-catch-finally);
  • catch块可以写多个,捕获不同类型的异常(针对性处理);
  • finally块可选,但只要写了,无论try里是否报错、catch里是否执行、甚至有return,都会执行;
  • 异常变量名一般写e(约定俗成,大家都这么写),可以通过e.getMessage()获取异常的具体原因,e.printStackTrace()打印详细的错误信息(调试用)。
  • 入门示例 1:处理运行时异常(除以 0,ArithmeticException)

    最基础的try-catch-finally用法,处理新手最容易犯的 “除以 0” 错误:

    public class ExceptionTest1 {
    public static void main(String[] args) {
    int a = 10;
    int b = 0;
    int result = 0; // 初始化结果,避免未赋值报错

    try {
    // 可能出问题的代码:除以0,会触发ArithmeticException
    result = a / b;
    System.out.println("两数相除结果:" + result); // 异常后,这行代码不会执行
    } catch (ArithmeticException e) {
    // 捕获算术异常,处理逻辑:提示错误
    System.out.println("出错啦!原因:不能除以0");
    // 可选:打印详细错误信息(开发调试用,上线后可注释)
    // e.printStackTrace();
    } finally {
    // 无论是否出错,一定执行:收尾提示
    System.out.println("异常处理代码执行完毕");
    }

    // 有异常处理,程序不会终止,这里能正常执行
    System.out.println("程序继续运行,不受异常影响");
    }
    }

    运行结果:

    出错啦!原因:不能除以0
    异常处理代码执行完毕
    程序继续运行,不受异常影响

    ✅ 效果:原本会让程序终止的 “除以 0” 错误,被捕获处理后,程序能继续运行!

    入门示例 2:多 catch 块(处理多种不同异常)

    当try里的代码可能触发多种异常时,写多个catch块,针对性处理(比如同时可能除以 0、空指针):

    public class ExceptionTest2 {
    public static void main(String[] args) {
    int a = 10;
    int b = 0;
    String s = null; // 空字符串,调用length()会触发空指针

    try {
    int result = a / b; // 可能触发ArithmeticException
    s.length(); // 可能触发NullPointerException(若上面代码没触发异常)
    } catch (ArithmeticException e) {
    // 专门处理除以0异常
    System.out.println("处理算术异常:不能除以0");
    } catch (NullPointerException e) {
    // 专门处理空指针异常
    System.out.println("处理空指针异常:对象不能为null");
    } catch (Exception e) {
    // 万能异常捕获:所有异常的父类,捕获上面没写到的其他异常
    System.out.println("处理其他未知异常:" + e.getMessage());
    } finally {
    System.out.println("多catch块的收尾操作");
    }
    }
    }

    运行结果:

    处理算术异常:不能除以0
    多catch块的收尾操作

    ✅ 关键:Exception是所有 Java 异常的父类,写在最后一个catch块,能捕获所有未明确声明的异常,避免漏捕。

    入门示例 3:finally 的核心作用 —— 释放资源(必用场景)

    开发中finally最常用的场景是关闭资源(比如 Scanner、文件流、数据库连接),无论是否发生异常,资源必须关闭,否则会占用系统内存,这是编程好习惯!

    import java.util.Scanner;
    import java.util.InputMismatchException;

    public class ExceptionTest3 {
    public static void main(String[] args) {
    Scanner sc = null; // 先声明为null,方便finally中关闭
    try {
    sc = new Scanner(System.in);
    System.out.print("请输入一个整数:");
    int num = sc.nextInt(); // 输入字母会触发InputMismatchException
    System.out.println("你输入的整数是:" + num);
    } catch (InputMismatchException e) {
    System.out.println("出错啦!你输入的不是整数");
    } finally {
    // 无论是否输入正确,都关闭Scanner,释放输入流资源
    if (sc != null) { // 判空:避免sc为null时调用close()触发空指针
    sc.close();
    System.out.println("Scanner已关闭,资源释放");
    }
    }
    }
    }

    运行场景 1:输入正确(整数 10)

    请输入一个整数:10
    你输入的整数是:10
    Scanner已关闭,资源释放

    运行场景 2:输入错误(字母 a)

    请输入一个整数:a
    出错啦!你输入的不是整数
    Scanner已关闭,资源释放

    ✅ 效果:无论输入是否正确(是否触发异常),finally里的关闭资源代码一定会执行!

    四、处理编译时异常的 2 种方式(编译器强制要求,二选一)

    编译时异常(如 IOException)的特点是不处理编译就报错,Java 提供了2 种合法处理方式,零基础记住 “二选一” 即可,不用纠结,根据场景选择。

    方式 1:try-catch-finally 捕获处理(推荐,主动处理异常)

    和处理运行时异常的语法完全一样,把可能触发编译时异常的代码放进try块,catch块处理即可,编译器就不会报错了。

    示例:处理控制台输入的 IOException(编译时异常)

    // 必须导入io包,否则编译报错
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.IOException; // 编译时异常

    public class CheckedExceptionTest1 {
    public static void main(String[] args) {
    BufferedReader br = null;
    try {
    // 这行代码会触发IOException(编译时异常),必须处理
    br = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("请输入一句话:");
    String line = br.readLine();
    System.out.println("你输入的是:" + line);
    } catch (IOException e) {
    // 捕获并处理IOException
    System.out.println("输入异常:" + e.getMessage());
    } finally {
    // 关闭资源,避免内存泄漏
    if (br != null) {
    try {
    br.close(); // close()也会触发IOException,嵌套try-catch即可
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }

    ✅ 效果:用try-catch捕获后,编译器不再报错,程序正常编译运行。

    方式 2:throws 声明异常(甩锅,把异常交给上层处理)

    在方法名后面加throws 异常类型,表示 “这个方法里可能触发该异常,我不处理,交给调用这个方法的上层代码处理”。

    • 若主方法(main)用throws声明,就表示把异常交给JVM(Java 虚拟机) 处理,JVM 的处理方式是:打印错误信息,终止程序(和未处理运行时异常的效果一样);
    • 适合快速开发、测试场景,生产环境不推荐主方法用 throws(会导致程序终止)。
    示例:main 方法 throws 声明 IOException,甩锅给 JVM

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.IOException;

    // main方法后加throws IOException,声明该方法可能抛出此异常,交给JVM处理
    public class CheckedExceptionTest2 {
    public static void main(String[] args) throws IOException {
    // 触发IOException的代码,无需try-catch,编译器不报错
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("请输入一句话:");
    String line = br.readLine();
    System.out.println("你输入的是:" + line);
    br.close();
    }
    }

    ✅ 效果:编译器不报错,程序能正常运行;若触发异常,JVM 会打印红色错误信息,程序终止。

    两种方式对比(零基础怎么选?)

    处理方式try-catch-finally 捕获throws 声明异常
    核心思想 主动处理,解决异常 被动甩锅,交给上层处理
    程序影响 异常处理后,程序可继续运行 上层若未处理,触发后程序直接终止
    适用场景 生产环境、需要程序优雅运行的场景 测试场景、快速开发,无需处理异常
    推荐程度 高(开发首选) 低(仅临时使用)

    五、2 个进阶关键字:throw(主动抛异常)、throws(声明异常)

    零基础掌握上面的try-catch-finally就够日常开发了,这里简单讲throw和throws的区别(很多小白容易混淆),了解即可,后续进阶再深入使用。

    1. throw —— 手动 / 主动抛出一个异常(方法内部用)

    作用

    在代码中主动触发一个异常(比如判断用户输入的年龄是负数,主动抛异常提示),让程序进入异常处理流程。

    语法

    throw new 异常类型("异常提示信息");

    示例:主动抛出非法参数异常(IllegalArgumentException,运行时异常)

    public class ThrowTest {
    public static void main(String[] args) {
    int age = -10; // 非法年龄:负数
    try {
    // 判断年龄非法,主动抛异常
    if (age < 0) {
    throw new IllegalArgumentException("年龄不能为负数!你输入的是:" + age);
    }
    System.out.println("你的年龄是:" + age);
    } catch (IllegalArgumentException e) {
    // 捕获主动抛出的异常,处理提示
    System.out.println("捕获异常:" + e.getMessage());
    }
    }
    }

    运行结果:

    捕获异常:年龄不能为负数!你输入的是:-10

    ✅ 效果:通过throw主动触发异常,替代了 “程序自动触发异常”,实现了自定义异常触发条件。

    2. throws —— 声明方法可能抛出的异常(方法名后面用)

    作用

    告诉调用者 “这个方法内部可能会抛出这些异常,我没处理,你自己看着办”,就是之前讲的 “甩锅”,和throw是完全不同的东西(一个是声明,一个是执行)。

    示例:方法内 throw 异常,方法名后 throws 声明

    public class ThrowsTest {
    // 方法名后throws声明:该方法可能抛出IllegalArgumentException
    public static void checkAge(int age) throws IllegalArgumentException {
    if (age < 0) {
    // 方法内部throw,主动抛异常
    throw new IllegalArgumentException("年龄不能为负数");
    }
    System.out.println("年龄合法:" + age);
    }

    public static void main(String[] args) {
    try {
    // 调用有throws声明的方法,要么try-catch处理,要么main方法也throws
    checkAge(-5);
    } catch (IllegalArgumentException e) {
    System.out.println("处理异常:" + e.getMessage());
    }
    }
    }

    运行结果:

    处理异常:年龄不能为负数

    throw 和 throws 核心区别(一张表分清,不混淆)

    关键字使用位置作用语法形式
    throw 方法内部 主动 / 手动抛出一个异常 throw new 异常类型(信息);
    throws 方法名后面 声明方法可能抛出多个异常 方法名() throws 异常1,异常2{}

    六、零基础异常处理的 5 个黄金原则(避坑必备,直接套用)

    学完语法,更重要的是养成良好的异常处理习惯,这 5 个原则都是开发中总结的实战经验,零基础严格遵守,能避开 90% 的异常坑!

    原则 1:局部变量必须初始化,避免 “未初始化” 导致的异常

    方法内的局部变量(如int a;)没有默认值,若未赋值就使用,要么编译报错,要么运行时触发异常,声明时直接赋初始值(如int a = 0; String s = "";)。

    原则 2:调用对象的方法 / 属性前,先判空(避免空指针)

    空指针(NullPointerException)是开发中最常见的异常,只要调用对象的方法 / 属性(如s.length()),先加if (对象 != null)判空,再使用。

    原则 3:资源使用后必须关闭,且关闭前要判空

    使用 Scanner、文件流、数据库连接等资源后,一定要在finally块中关闭,关闭前必须判空(if (sc != null)),避免关闭 null 对象触发空指针。

    原则 4:catch 块要针对性处理,不要只写一个 Exception

    虽然Exception能捕获所有异常,但开发中要尽量写具体的异常类型(如ArithmeticException、InputMismatchException),针对性处理(比如除以 0 提示 “不能除 0”,输入错误提示 “类型不对”),方便调试和用户理解。

    原则 5:运行时异常尽量处理,编译时异常必须处理

    • 运行时异常(如下标越界)是程序员粗心导致,尽量用try-catch处理,避免程序运行时突然终止;
    • 编译时异常(如 IOException)是 Java 强制要求,要么try-catch捕获,要么throws声明,二选一,不处理编译不过。

    七、零基础快速上手总结(核心知识点浓缩,一分钟回顾)

  • 异常是什么:程序运行时的错误 / 意外,未处理会导致程序终止;
  • 异常分两类:运行时异常(编译不强制处理,程序员粗心导致)、编译时异常(编译必须处理,客观原因导致);
  • 核心处理语法:try-catch-finally,try放可能出问题的代码,catch处理异常,finally做收尾(关闭资源);
  • 编译时异常二选一:要么try-catch捕获,要么throws声明甩锅;
  • 两个进阶关键字:throw(方法内主动抛异常)、throws(方法后声明可能抛的异常);
  • 5 个黄金原则:变量初始化、对象判空、资源关闭、针对性 catch、编译时异常必处理。
  • 至此,Java 异常的核心知识点已经全部讲完,零基础小白按照本文的模板套代码,就能轻松实现异常处理,让你的 Java 程序更健壮、更优雅!文章如有错误欢迎私信我,我会及时解决,如果我的内容对你有帮助和启发,请点赞、评论、收藏。你们的支持就是我更新最大的动力,那么我们下期再见!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » java异常详解:为0基础小白专门打造,帮助你学会异常处理!
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!