Java基础:异常(三)
文章目录
- Java基础:异常(三)
- 1. Java异常体系
- 1.1 错误的分类
- 1.2 异常的分类
- 2. 异常的捕获与处理
- 2.1 try-catch
- 2.2 finally
- 3. 异常的抛出
- 4. 自定义异常
1. Java异常体系
Java的异常体系是Java中用于处理运行时错误和其他异常情况的重要机制。它基于一个层次结构,其中
Throwable
是所有错误和异常的基类。在Java中,主要有两种类型的可抛出对象:Error
和Exception
。Java的异常体系,可以保证程序的健壮性。
1.1 错误的分类
Java中的程序错误分为三类:
- 编译错误(
Compilation Error
):编译错误是在程序源代码被编译器处理(即编译)成可执行文件时发生的错误,这些错误通常是由于违反了编程语言的语法规则或编译器无法理解的代码结构造成的。 - 运行错误(
Runtime Error
):运行错误是程序在运行时(即执行时)发生的错误,这些错误通常是由于程序试图执行无效的操作或访问不存在的资源造成的。在Java中,运行错误通常表现为异常(Exception
)。异常是一种特殊的对象,用于表示程序运行时的错误情况。 - 逻辑错误(
Logical Error
): 逻辑错误是程序在逻辑上不正确或不符合预期的错误,这些错误通常是由于程序员的编程逻辑错误或对问题的不正确理解造成的。逻辑错误不会导致程序崩溃或产生异常,但会导致程序产生不正确的结果或行为。
1.2 异常的分类
Java中的异常分为两类:
- 检查型异常(
Checked Exception
):检查型异常在编译时会被检查,如果方法可能抛出检查型异常,但该方法没有使用throws
关键字声明该异常,或者没有捕获该异常,那么编译器会报错。
检查型异常 | 说明 |
---|---|
IOException | 输入输出流异常 |
SQLException | SQL异常 |
FileNotFoundException | 文件找不到异常 |
ClassNotFoundException | 类找不到异常 |
InterruptedException | 线程中断异常 |
- 非检查型异常(
Unchecked Exception
):未检查型异常是指RuntimeException
(运行时异常)类及其子类异常,在编译时不会被检查,它们通常是由程序逻辑错误引起的。
运行时异常 | 说明 |
---|---|
RuntimeException | 运行时异常父类 |
ArithmeticException | 算术异常,如除零操作 |
ArrayIndexOutOfBoundsException | 数组下标越界异常 |
NullPointerException | 访问null对象引用 |
NumberFormatException | 数字格式异常 |
java.lang.ClassCastException | 类型转换异常 |
2. 异常的捕获与处理
2.1 try-catch
在一个try
块中,可能会产生多个异常,在后面可以接多个catch
,去捕捉不同的异常。如果try
块中,出现异常,直接进入对应的catch
块中,try
块中出现异常后的代码不会继续执行。语法格式如下:
try {
// 尝试执行可能会抛出异常的代码
// ...
} catch (ExceptionType1 e) {
// 处理ExceptionType1类型的异常
// ...
} catch (ExceptionType2 e) {
// 处理ExceptionType2类型的异常
// ...
}
// 可以有多个catch块来处理不同类型的异常
从JDK7版本之后,可以在一个catch
块中,捕捉多个异常。代码示例如下:
package com.coder.exception;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入两个数:");
int x = scanner.nextInt();
int y = scanner.nextInt();
int m[] = new int[10];
try {
int z = x / y; // y=0
System.out.println(z);
m[10] = 10; // 数组下标越界
System.out.println(m[10]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) { // >=JDK7版本
// 获取错误消息
System.out.println("出现错误:" + e.toString());
}
}
}
🆚🆚运行结果:
请输入两个数:
10 2
5
出现错误:java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
请输入两个数:
10 0
出现错误:java.lang.ArithmeticException: / by zero
如果try
和catch
操作出现嵌套情况,内部的catch
如果不能处理内部try
代码块的异常,则由外部的catch
块进行捕捉。代码示例如下:
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入两个数:");
int x = scanner.nextInt();
int y = scanner.nextInt();
int m[] = new int[10];
try {
int z = x / y; // y=0
System.out.println(z);
try {
m[10] = 20; // 数组下标越界
System.out.println(m[10]);
//String str = null;
//System.out.println(str.toLowerCase());
} catch (NullPointerException e) { // 非检查型异常 空指针异常
System.out.println("数组下标越界");
}
} catch (ArithmeticException e) {
// 打印异常堆栈轨迹
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("外面的catch块处理数组下标越界");
}
}
}
🆚🆚运行结果:
请输入两个数:
10 2
5
外面的catch块处理数组下标越界
请输入两个数:
10 0
java.lang.ArithmeticException: / by zero
at com.coder.exception.Test.main(Test.java:18)
📌注:异常消息的处理包括:
e.getMessage()
,获取异常信息;e.toString()
,获取异常类和信息;e.printStackTrace()
,打印异常堆栈轨迹。
2.2 finally
以下是finally
的执行流程:
其语法格式如下:
try {
// 尝试执行可能会抛出异常的代码
} catch (具体的异常类 e) {
} finally {
//释放资源
}
- 使用
finally
完成资源释放。例如:关闭打开的连接,删除临时文件,关闭打开文件。 finally
不管是否出现异常,都会被执行到。如果try
和catch
块中,有return
语句,finally
在return
代
码之前执行。- 如果
try
或catch
代码块中,执行了System.exit(0)
退出虚拟机操作,finally
代码块中的语句不再执行。
代码示例如下:
public class Test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入两个数:");
int x = scanner.nextInt();
int y = scanner.nextInt();
int m = test(x, y);
System.out.println(m);
}
public static int test(int x, int y) {
System.out.println("进入test方法");
int z = 0;
try {
z = x / y; // y=0
System.out.println("除法执行完成");
System.exit(0); // 退出虚拟机操作
return z;
} catch (ArithmeticException e) {
return 0;
} finally {
System.out.println("关闭连接");
return -1;
}
}
}
🆚🆚运行结果:
请输入两个数:
10 2
进入test方法
除法执行完成
10 0
进入test方法
关闭连接
-1
📌注:
try
、catch
、finally
不能单独使用:
try
和catch
使用;try
、catch
和finally
使用;try
和finally
使用。
3. 异常的抛出
- throws用法:用于声明一个方法可能会抛出的异常列表,但它并不处理这些异常。谁来调用这个方法,谁处理这些异常。
throws
后面可以接多个异常类型,中间使用逗号分隔。 - throw用法:使用
throw
抛出明确的异常处理,语法格式:throw new ExceptionType(parameters);
。throw
在方法体内的语句,如果抛出的是运行时异常,可以不需要做任何处理。如果抛出的是检查型异常,不能单独使用,必须要配合try-catch
或者throws
使用。
代码示例如下:
public class Test4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入姓名和年龄:");
String name = scanner.next();
int age = scanner.nextInt();
System.out.println("姓名:" + name + "," + "年龄:" + age);
Person person = new Person(name, age);
// 2. 使用try-catch块:处理检查型异常时,在调用方法的代码周围使用try-catch块来捕获并处理异常。
try {
checkPersonInfo(person);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// 1. 在方法签名中使用throws关键字:如果你不想在当前方法中处理异常,你可以使用throws关键字将异常声明给方法的调用者。
public static void checkPersonInfo(Person person) throws FileNotFoundException {
if (person.getAge() < 18) {
throw new NullPointerException("年龄必须在18岁以上"); // 使用throw抛出运行型异常
}
if (person.getName().length() < 2) {
throw new FileNotFoundException("姓名必须是2位以上"); // 使用throw抛出检查型异常,必须要配合try-catch或者throws使用
}
}
}
🆚🆚运行结果:
请输入姓名和年龄:
张三 10
姓名:张三,年龄:10
Exception in thread "main" java.lang.NullPointerException: 年龄必须在18岁以上
at com.coder.exception.Test4.checkPerName(Test4.java:30)
at com.coder.exception.Test4.main(Test4.java:21)
请输入姓名和年龄:
张 18
姓名:张,年龄:18
java.io.FileNotFoundException: 姓名必须是2位以上
at com.coder.exception.Test4.checkPerName(Test4.java:33)
at com.coder.exception.Test4.main(Test4.java:21)
📌注:
- 运行时异常通常表示编程错误或不可恢复的错误情况,如数组越界、空指针引用等。因此,在编写代码时应该尽量避免抛出运行时异常,除非确实出现了无法恢复的错误。
- 与检查型异常不同,运行时异常在方法签名中不需要使用
throws
关键字来声明。这是因为运行时异常在编译时期不会被检查,所以编译器不会强制要求你处理这些异常。- 虽然运行时异常在编译时期不需要被显式处理,但在实际编程中,最好还是捕获并处理这些异常,以确保程序的健壮性和可维护性。
4. 自定义异常
自定义异常是指在Java程序中根据特定业务需求创建的异常类,这些类继承自Exception
类或其子类(如RuntimeException
),以提供更详细的错误信息和更准确地表达特定的业务含义。代码示例如下:
public class AgeException extends Exception{
public AgeException(){
super("年龄不符合要求");
}
public AgeException(String message){
super(message);
}
}
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
以上内容是关于Java异常的基础知识,希望对初学者或再次学习者有所帮助,基础打扎实,不怕风吹雨打!如果以上内容有错误或者内容不全,望大家提出!我也会继续写好每一篇博文!
👍👍👍
待续未完
🙊🙊🙊
欢迎观看和提问!!!
👏👏👏