转载自博主Mikey棒棒棒:
1. Throwable和Exception之间的关系
Throwable 是所有异常和错误的基类,它有两个直接子类:Exception 和 Error。Exception 表示程序运行时可以捕获和处理的异常,而 Error 则表示更严重的系统错误,通常无法恢复。
Exception 下的子类进一步分为已检查异常和未检查异常。已检查异常必须在编译时进行处理,而未检查异常(即 RuntimeException 及其子类)则是运行时异常,通常代表编程中的错误,编译器不强制处理。
2.异常分为哪两大类
已检查异常(Checked Exception)属于继承自 Exception,但不包括继承自 RuntimeException 的异常。这类异常在编译时会被检查,要求必须通过 try-catch 或 throws 来处理。常见的已检查异常有 IOException、SQLException、FileNotFoundException 等。这些异常通常表示外部环境或资源的问题,如文件未找到、网络连接失败等。
未检查异常(Unchecked Exception)包括 RuntimeException 和 Error,编译器不会强制要求处理。它们通常代表编程中的逻辑错误或系统级问题。常见的未检查异常有 NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException 等。
3.常见的 RuntimeException
NullPointerException:当程序试图访问 null 对象时发生。
ArrayIndexOutOfBoundsException:当数组访问越界时发生。
ArithmeticException:当出现算术错误(如除以零)时抛出。
ClassCastException:当试图将对象转换为不兼容的类型时抛出。
IllegalArgumentException:当传递给方法的参数不合法时抛出。
IllegalStateException:当对象的状态不适合调用某方法时抛出。
NumberFormatException:当无法将字符串转换为数值类型时抛出。
4. 常见的 Error
Error 通常由 JVM 抛出,表示系统级别的严重错误。常见的有:
OutOfMemoryError:当 JVM 无法分配足够的内存时抛出。
StackOverflowError:当递归调用过深导致栈内存溢出时抛出。
VirtualMachineError:JVM 内部出现无法恢复的错误时抛出。
NoClassDefFoundError:当 JVM 运行时找不到类定义时抛出。
5.什么是已检查异常和未检查异常?它们的区别是什么?
已检查异常(Checked Exception)是在编译时被检查的异常,意味着编译器要求必须处理它们(使用 try-catch 或 throws 声明)。常见的已检查异常包括 IOException、SQLException 等。这类异常通常是程序无法控制的外部情况(例如文件读取失败或数据库连接失败)。
未检查异常(Unchecked Exception)包括 RuntimeException 及其子类,编译器不强制要求处理它们。这类异常通常是程序中的逻辑错误或意外情况,例如 NullPointerException、ArrayIndexOutOfBoundsException 等。它们发生在运行时,通常可以通过修复代码来避免。
区别:
已检查异常:编译时必须处理,外部情况导致。
未检查异常:编译时不强制处理,通常是程序中的逻辑错误。
6.Java 中如何自定义异常?
Java 支持自定义异常类,可以通过继承 Exception(用于已检查异常)或 RuntimeException(用于未检查异常)来创建自己的异常类。
7.throw 和 throws 的区别是什么?
throw
throw 关键字 用于显式地抛出一个异常。
可以抛出任何 Throwable 类型的对象(包括 Exception 和 Error)。
通常在方法体或代码块内部使用,当某种条件不满足时,手动抛出异常。
throws
throws 关键字 用于声明一个方法可能抛出的异常类型。
它位于方法签名中,告诉调用者该方法可能抛出某种类型的异常,调用者必须处理这个异常(通过 try-catch 块,或者继续使用 throws 抛出)。
常用于处理 已检查异常,如 IOException 或 SQLException。
8.什么是 finally 块?在什么情况下 finally 块不会被执行?
finally 块是 Java 异常处理结构的一部分,通常与 try 和 catch 一起使用。它的作用是确保不论是否发生异常,finally 块中的代码都会执行(例如,释放资源、关闭文件等)。
但在少数情况下,finally 块不会执行:
如果在 try 或 catch 块中调用了 System.exit()。
如果线程被中断或杀死(例如 JVM 崩溃)。
如果在 finally 之前的代码块中发生了非捕获的致命错误,如硬件故障。
System.exit() 是 Java 中用于终止当前 Java 虚拟机(JVM)运行的静态方法。调用这个方法会立即停止程序的执行,并终止所有正在运行的线程。
9. try/catch/finally的return顺序
1.try 块:如果 try 块中有 return 语句,Java 会保存该返回值,但是在执行 return 之前会先执行 finally 块。
2.catch 块:如果 catch 块中有 return 语句,Java 同样会保存返回值,但是仍会在执行 return 前先执行 finally 块。
3.finally 块:不论 try 或 catch 中是否有 return,finally 块中的代码都会在 return 之前执行。如果 finally 块中也有 return,它将覆盖 try 或 catch 中的返回值,即 finally 块中的 return 会最终生效。