Exception 和 Error
Exception 和 Error
在Java中,Throwable是所有异常类的父类。它有两个子类:Error和Exception。
Error表示系统错误或者资源耗尽等问题,通常情况下不应该捕获这些异常,而是让程序自然退出并由系统进行处理。比如OutOfMemoryError、StackOverflowError等都属于Error。
Exception则是可以被程序本身处理的异常,分为运行时异常(RuntimeException)和检查性异常(CheckedException)。
- 运行时异常是指在编程过程中可以预料到的异常,但是有可能因为疏忽大意等原因没有被捕获,比如NullPointerException、ClassCastException等;
- 检查性异常则是编译器强制要求程序必须处理的异常,比如IOException、SQLException等。
总的来说,Error表示严重的系统级别错误,无法通过程序本身进行修复,只能依赖于操作系统等外部因素进行处理,而Exception则是可以通过程序本身进行处理的异常。
代码分析
第一条: 准确捕获具体的异常.
try {
// 业务代码
// …
Thread.sleep(1000L);
} catch (Exception e) {
// Ignore it
}
这段代码中的try-catch语句会捕获所有Exception类及其子类的异常,并在catch块中忽略它们。这样做虽然不会导致程序直接崩溃,但是也可能会掩盖一些潜在的问题,在调试和排查故障时造成困难。
更好的做法是,尽可能地精确捕获并处理异常。
比如只想要捕捉InterruptedException这个异常.
try {
// 业务代码
// …
Thread.sleep(1000L);
} catch (InterruptedException e) {
// 处理InterruptedException异常
}
这样就能够有效地处理该异常,并且对其他类型的异常仍然进行抛出。当然,在实际开发中,应该根据具体情况进行判断,尽可能地避免产生异常,从而提高程序的稳定性和可靠性。
第二条:不要生吞异常.
这样就能够有效地处理该异常,并且对其他类型的异常仍然进行抛出。当然,在实际开发中,应该根据具体情况进行判断,尽可能地避免产生异常,从而提高程序的稳定性和可靠性。
try {
// 读取文件并计算平均值
double avg = readAndCalculateAverage("data.txt");
// 处理平均值
handleAverage(avg);
}
catch (FileNotFoundException e) {
// 处理文件不存在的情况
System.out.println("文件不存在,请检查文件名和路径!");
}
catch (NumberFormatException e) {
// 处理文件内容不是数字的情况
System.out.println("文件内容无效,请检查文件格式!");
}
catch (IOException e) {
// 处理其他 IO 异常
System.out.println("发生了 IO 异常,请检查文件读取操作!");
}
catch (Exception e) {
// 处理其他未知异常
System.out.println("发生了未知异常,请检查程序逻辑!");
}
在这个示例中,我们使用了四个 catch 块来捕获可能出现的异常,分别处理不同的异常情况。如果程序中出现其他未知异常,我们也可以使用一个最后的 catch 块来捕获它并打印错误信息。
性能角度的Java异常的分析:
- try-catch 代码段会产生额外的性能开销,或者换个角度说,它往往会影响 JVM 对代码
进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;与
此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句
(if/else、switch)要低效。 - Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个相对比较重的操
作。如果发生的非常频繁,这个开销可就不能被忽略了。