[JavaSE] 第六章 异常
6.1 异常概述与异常体系结构
-
异常:在Java语言中,将程序执行中发生的不正常情况称为异常
-
Java程序在执行过程中所发生的异常事件可分为两类:
-
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源
耗尽等严重情况。比如:StackOverflowError 和 OOM。一般不编写针对性
的代码进行处理
-
Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使
用针对性的代码进行处理
-
6.2 异常处理机制一:try-catch-finally
- finally 是可选的
- finally 中声明的是一定会被执行的代码。即使 catch 中有出现异常,try 中有 return 语句,catch 中有 return 语句等情况
- 使用 try 将可能出现的异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个异常类的对象,根据此对象的类型,去 catch 中进行匹配
- 一旦 try 中的异常对象匹配到某一个 catch 时,就进行 catch 中进行异常的处理。一旦处理完成,就跳出当前的 try-catch 结构(在没有写 finally 的情况)。继续执行其后的代码
- catch 中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓
- catch 中的异常类型如果满足子父类关系,则要求子类一定要声明在父类上面
- 在 try 结构中声明的变量,在出了 try 结构以后,就不能再被调用
- 常见的异常对象处理的方式:
- String getMessage()
- printStackTrance()
用 try-catch-finally 处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用 try-catch-finally 将一个编译时可能出现的异常延迟到运行时出现
开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写 try-catch-finally了。针对编译时异常,我们一定要考虑异常的处理
public class ExceptionTest1 {
@Test
public void test1() {
//NumberFormatException
String str = "123";
str = "abc";
int num = 0;
try {
num = Integer.parseInt(str);
System.out.println("hello--1");
} catch (NumberFormatException e) {
System.out.println(e.getMessage());
//e.printStackTrace();
//System.out.println("出现数值转换异常");
}
System.out.println(num);
System.out.println("hello--2");
}
@Test
public void test2() {
try {
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while (data != -1) {
System.out.println(data);
data = fis.read();
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
6.4 异常处理机制二:throws
异常处理的方式二:throws + 异常类型
"throws + 异常类型" 写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
一旦方法体执行时,出现异常,仍会在异常代码生成一个异常类的对象,此对象满足throws后异常
类型时,就会被抛出
- try-catch-finally 真正的将异常给处理掉了。
- throws 的方式只是将异常抛给了方法的调用者,并没有真正的将异常处理掉。
- 开发中如何选择使用 try-catch-finally 还是使用 throws?
- 如果父类中被重写的方法没有 throws 方式处理异常,则子类重写的方法也不能使 throws,意味着如果子类重写的方法中有异常,必须使用 try-catch-finally 方式处理异常
- 执行的方法 a 中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。建议这几个方法使用 throws 的方式进行处理。而执行的方法 a 可以考虑使用 try-catch-finally 方式进行处理
public class ExceptionTest2 {
public static void main(String[] args) {
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void method2() throws IOException {
method1();
}
@Test
public static void method1() throws IOException {
File file = new File("../data/hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while (data != -1) {
System.out.println(data);
data = fis.read();
}
fis.close();
}
}
6.5 手动抛出异常:throw
- 关于异常对象的产生:
-
系统自动生成的异常对象
-
手动的生成一个异常对象,并抛出(throw)
-
public class StudentTest {
public static void main(String[] args) {
Student s = new Student();
try {
s.register(-100);
System.out.println(s);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
class Student {
private int id;
public void register(int id) {
if (id > 0) {
this.id = id;
} else {
//手动抛出异常对象
throw new MyException("您输入的数据非法");
}
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
'}';
}
}
/*
您输入的数据非法
com.syr.MyException: 您输入的数据非法
at com.syr.Student.register(StudentTest.java:22)
at com.syr.StudentTest.main(StudentTest.java:5)
*/
6.6 用户自定义异常类
- 如何自定义异常类?
- 继承现有的异常结构:RuntimeException、Exception
- 提供全局常量:serialVersionUID
- 提供重载的构造器
public class MyException extends RuntimeException {
static final long serialVersionUID = -70348972395766939L;
public MyException() {}
public MyException(String msg) {
super(msg);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现