Error是java程序运行中不可预料的非正常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等;
Exception是java程序运行中可预料的异常情况,可以获取到这种异常,并且对这种异常进行业务外的处理。Exception又分为检查性异常和非检查性异常。
可以从以下四个方面进行回答:
相同点:Exception和Error都继承了Throwable类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。
不同点:Exception 和 Error 体现了不同异常情况的分类。可以说Error是天灾,出现了也恢复不了;Exception是人祸,出现了可以有对应的解决措施。"Error"通常表示严重的问题,很难通过程序来处理,而"Exception"则更广泛地表示可以通过代码处理的异常情况。
异常可以分为三个主要类别:
在Java中,异常处理使用以下关键字:
比如直接捕获Exception或Throwable,不利于定位异常位置,这可能会隐藏程序中的潜在问题。在业务开发中更建议自定义异常,可以根据异常快速定位业务问题;
try {
// 业务代码
// …
Thread.sleep(1000L);
} catch (Exception e) {
// Ignore it
}
在这里是 Thread.sleep() 抛出的 InterruptedException。这是因为在日常的开发和合作中,我们读代码的机会往往超过写代码
要不然会出现异常难以诊断的诡异情况。在业务开发中哪怕不抛出异常,也要在异常位置打出关键日志。
生吞异常,往往是基于假设这段代码可能不会发生,或者感觉忽略异常是无所谓的,但是千万不要在产品代码做这种假设!如果不把异常抛出来,或者也没有输出到日志(Logger)之类,程序可能在后续代码以不可控的方式结束。没人能够轻易判断究竟是哪里抛出了异常,以及是什么原因产生了异常。
try {
// 业务代码
// …
} catch (IOException e) {
e.printStackTrace();
}
这段代码是没有任何问题的,但在开发中通常都不允许这样处理。这是因为printStackTrace()采用的是标准出错(STERR)的输出选项,很难判断出到底输出到哪里去了。如果程序就会抛出异常,但是由于没有第一时间暴露出问题,堆栈信息可能非常令人费解,往往需要相对复杂的定位。
在发现问题的时候,第一时间抛出,能够更加清晰地反映问题。尤其是对于分布式系统,如果发生异常,但是无法找到堆栈轨迹(stacktrace),这纯属是为诊断设置障碍。所以,最好使用产品日志,详细地输出到日志系统里。
异常捕获在性能角度考虑会产生额外的开销,所以也要注意尽量不要捕获非必要的代码,捕获范围尽量小。从性能角度来审视一下 Java 的异常处理机制,这里有两个可能会相对昂贵的地方:
这也是一个比较经典异常处理的面试题目。NoClassDefFoundError 和 ClassNotFoundException 都是 Java 中与类加载有关的异常,但它们发生的上下文和原因略有不同。
// NoClassDefFoundError 示例
public class ExampleNoClassDefFoundError {
public static void main(String[] args) {
try {
// 编译时存在类,但运行时找不到
Class.forName("com.example.NonExistentClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
在上述示例中,ExampleNoClassDefFoundError 中使用 Class.forName() 尝试加载一个编译时存在但运行时找不到的类,可能导致 NoClassDefFoundError。
// ClassNotFoundException 示例
public class ExampleClassNotFoundException {
public static void main(String[] args) {
try {
// 试图加载不存在的类
ClassLoader.getSystemClassLoader().loadClass("com.example.NonExistentClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
在上述示例中, ExampleClassNotFoundException 中使用 ClassLoader.loadClass() 尝试加载一个不存在的类,可能导致 ClassNotFoundException。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。