Java异常处理(基础完结撒花~)
实际工作中,我们写的程序可能会遇到各种各样的问题。比如用户的输入不符合我们的要求;打开某个文件时这个文件可能不存在或者格式不对;读取数据库时数据库可能是空的;程序运行中内存或者硬盘可能满了,甚至Jvm也会报错等等。
遇到这些突发情况的时候我们的程序将会无法执行跑不下去。这种情况我们就叫做异常(Exception)。
异常的突然出现使我们的程序无法按照正常的流程执行,为了让我们的程序正常被执行,我们面对可能会发生的这些异常必须在代码中给出合理的处理,这就是异常处理机制。
简单分类
要理解我们的Java异常处理是如何工作的,需要至少掌握以下三种类型。
-
检查性异常
最具代表性的异常,指用户错误或问题引起的异常,这种异常是我们写程序的时候无法被预见的。例如我们的程序需要打开某一个文件,而这个文件实际在磁盘中不存在时一个异常就发生了。
-
运行时异常
运行时异常是可能在我们写程序的时候被避免的异常,与检查性异常相反,运行时异常可以在编译的时候被忽略,因为语法上并没有任何问题。
-
ArrayIndexOutOfBoundsException(数组索引越界)
-
NullPointerException(空指针)
-
ArithmeticException(算数异常)
-
MissingResourceException(资源丢失)
-
ClassNotFoundException(不存在的类)
运行时异常通常是我们的程序产生了逻辑错误导致的,我们需要尽可能从逻辑的角度避免这类异常的发生。
-
-
错误(Error)
错误不是异常,而是程序脱离控制的问题。错误通常在代码中被忽略。比如栈溢出时,一个错误就发生了,这种错误在编译时是无法检测到的。
-
OutOfMemoryError(内存不足)
-
NoClassDefFoundError(类定义错误)
-
LinkageError(链接错误)
错误一般是由于JVM生成并抛出的,大多数错误与我们代码编写者执行的操作无关。
-
异常处理
Java中,异常被当做对象处理。Java定义了一个基类java.lang.Throwable为所有异常的超类,超类往下又统分为Exception类和Error类。
Java给了我们五个关键字用来处理异常:
-
try
指定监控区域。
-
catch
捕获异常。
-
finally
善后处理。
-
throw
主动抛出异常,一般在方法中使用。
-
throws
同throw一样,主动抛出异常,区别是抛到方法外。
示例代码:
public class Demo20 {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
//异常监视
System.out.println(a / b);
} catch (Exception e) {
//异常处理
System.out.println("被除数“b”不能为0");
} finally {
System.out.println("finally常用来执行一些线程的关闭。");
}
}
}
运行结果:
示例代码:
public class Demo20 {
public static void main(String[] args) {
int a = 1;
int b = 0;
System.out.println(divide(a, b));
}
public static int divide(int a, int b) {
if (b == 0) {
try {
//直接在方法中抛出异常并处理。
throw new ArithmeticException();
} catch (ArithmeticException e) {
System.out.println("被除数“b”不能为0");
return 0;
}
} else {
return a / b;
}
}
}
运行结果:
示例代码:
public class Demo20 {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
System.out.println(divide(a, b));
} catch (ArithmeticException e) {
System.out.println("被除数“b”不能为0");
}
}
//将异常往方法外抛出,在主程序进行处理。
public static int divide(int a, int b) throws ArithmeticException {
return a / b;
}
}
运行结果:
总结
通过以上示例代码我们可以发现:
-
只要是处理异常基本都会用到try和catch语句,但finally并不是必须的。
-
不管try和catch代码块有没有捕获到异常,finally总会执行。
-
一个try代码块后面可以跟数个catch代码块,根据捕获到的异常不同,采取不同的应对方式。
-
当我们使用多个catch代码块的时候范围必须从小到大捕获异常,因为程序是从上往下执行的,如果在之前的catch代码块捕获到了异常则后面的catch代码块不会执行。
-
因为Java将异常和错误当做类处理,所以catch捕获的时候实际上是实例化了一个当前异常的对象”e“。
-
throws往方法外抛异常是当前方法如果产生对应的异常才会抛,如果没有异常则不会抛出异常。
-
throw和throws不同,不管是否产生异常,throw是只要执行到这个代码语句就一定会抛一个异常!
-
热知识:在IDEA中使用Ctrl+Alt+T可以快速生成代码块。
拓展
自定义异常
因为所有的异常都属于Exception类,我们自定义异常实际就是继承Exception类。
异常类示例代码:
/**
* 自定义一个异常,当变量 a > 10 时抛出。
*/
public class MyException extends Exception {
//私有字段
private int detail;
//构造方法
public MyException(int a) {
this.detail = a;
}
//Alt+Ins自动生成一个ToString框架用来打印异常信息
@Override
public String toString() {
return "MyException{" +
"detail=" + detail +
'}';
}
}
测试示例代码:
/**
* 自定义一个异常,当变量 a > 10 时抛出。
*/
public class Application {
public static void main(String[] args) {
int a = 11;
//捕获并处理异常
try {
//调用抛异常的方法。
new Application().test(a);
} catch (MyException e) {
//直接打印异常信息到控制台
e.printStackTrace();
}
}
//写一个可能会抛出异常的方法,抛到主程序去处理。
public int test(int a) throws MyException {
if (a > 10) {
//主动抛出异常
throw new MyException(a);
}
//因为执行到异常后方法会“终止”所以这里就不写else了
return a;
}
}
测试结果:
因为catch捕获到之后没有对异常进行其他处理,只是单纯的打印了异常信息,所以看起来跟没处理一样,实际是跟直接抛是不同的哦~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix