什么是运行时异常,什么是检查/未检查异常以及错误/异常之间的区别。为什么有这么多类型?相反,Java 可能只是遵循一个简单的设计(只是尝试/捕获所有类型)来处理程序中的异常情况?
8 回答
由于我是一名新的Java开发人员,因此在区分和处理不同类型的异常方面也遇到了一些困难。这就是为什么我在这个主题上做了一个简短的笔记,每当我感到困惑时,我都会仔细阅读。这是Throwable
类层次结构的图像:
[图片由JavaTpoint提供]。
这里要记住三个关键类Throwable
:Exception
和Error
。在这些类Exception
中可以分为两种类型:“Checked Exception”和“Unchecked Exception”。
检查异常:
- 这些是扩展
Throwable
exceptRuntimeException
和的类Error
。 - 它们也被称为编译时异常,因为它们在编译时进行检查,这意味着编译器强制我们处理它们
try/catch
或在函数签名中指出throws
它们并强制我们在调用者中处理它们。 - 它们是由代码无法控制的意外情况(例如数据库关闭、文件 I/O 错误、错误输入等)引起的可通过编程恢复的问题。
- 示例:
IOException
,SQLException
等。
未经检查的异常:
- 扩展的类
RuntimeException
称为未经检查的异常。 - 未经检查的异常不在编译时检查,而是在运行时检查,因此得名。
- 它们也是可通过编程方式恢复的问题,但与检查异常不同,它们是由代码流或配置中的错误引起的。
- 示例:
ArithmeticException
、NullPointerException
、ArrayIndexOutOfBoundsException
等。 - 由于它们是编程错误,因此可以通过巧妙/明智地编码来避免它们。例如,“除以零”会产生
ArithmeticException
,这可以通过对除数的简单检查来避免。同样,我们可以NullPointerException
通过简单地检查参考来避免:if (object != null)
甚至使用更好的技术。
错误:
Error
指的是无法恢复的情况,没有由 a 处理try/catch
。- 示例:
OutOfMemoryError
、VirtualMachineError
、AssertionError
等。
为什么会有这么多类型?
除了Stephen C的回答我想说:异常处理在 Java 中是一个相对昂贵的操作。我们不应该把所有异常情况都放在一个try/catch
块中。过度使用try/catch
s 可能会影响程序性能。
总之,Exception
应尽可能以编程方式处理 s。另一方面,我们无法处理Error
s,因此这些可能是存在多种异常的一些逻辑原因。
Throwable 在所有异常中都居于首位。在 Throwable 下面你有错误和异常。在异常下方,您有 RuntimeException。
Java 有两种类型的异常——已检查和未检查。已检查的异常由编译器强制执行(您必须在 throws 子句中声明它们并最终捕获它们)。在 throws 子句中捕获或声明未检查的异常不会被强制执行。
(答案有争议的部分)
Throwable 存在,因此所有异常类型都有一个父级。你永远不应该声明你抛出 Throwable 并且永远不会抓住它(除非你真的真的很清楚自己在做什么)。
存在错误表示运行时环境存在问题,您的程序可能无法从中恢复,例如格式错误的类文件或 VM 内存不足。除非您真的知道自己在做什么,否则不应捕获错误。
异常作为所有非程序员错误的根源存在(有关“异常”,请参阅 RuntimeException),例如由于磁盘已满而无法创建文件。您不应抛出、抛出或捕获异常。如果您必须捕获异常,请确保您知道自己在做什么。
RuntimeException 的存在表示所有程序员错误,例如超出数组末尾或调用空对象上的方法。这些是你应该修复的东西,这样它们就不会抛出异常——这表明你,程序员,搞砸了代码。同样,除非您知道自己在做什么,否则您不应该抓住这些。
TofuBeer 的回答清楚地解释了异常类的含义。
为什么会有这么多类型?相反,Java 可能只是遵循一个简单的设计(只是尝试/捕获所有类型)来处理程序中的异常情况?
为什么?因为它们是必需的!如果没有这 4 个类,按大类处理异常是不切实际的。
- 如果没有该类,您将如何捕获“所有致命的 JVM 错误”
Error
? - 如果没有类,你将如何捕获“所有不是 JVM 致命错误的异常”
Exception
? - 如果没有课程,您将如何捕获“所有未经检查的异常”
RuntimeException
?
- 错误(由 VM 抛出,不应被捕获或处理)
- 虚拟机错误
- 断言错误
- 联动错误...等等
- 运行时/取消检查异常(编程错误,不应被捕获或处理)
- 空指针异常
- ArrayIndexOutOfBoundException
- IllegalArgumentException ... 等等
- 检查异常(其他任何情况,应捕获或处理应用程序)
- IO异常
- FileNotFoundException
- SQLException ...等等
本文以简洁明了的方式总结了Checked和Unchecked异常。
Checked Exceptions: Checked Exceptions是可以在编译时检测、识别和检查的异常。如果代码块抛出已检查异常,则该方法必须处理该异常,或者必须使用
throws
关键字指定异常。示例:
public void testDB() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); System.out.println("Driver Loaded"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/selenium","root","root"); System.out.println("Connected to MySQL DB"); }
我们要么需要使用 throws 指定异常列表,要么需要使用
try-catch{}
block。throws
我已经在下面的程序中演示了的用法。
未经检查的异常:在编译时不检查未经检查的异常。
Error
和RuntimeException
类下的 Java 异常是未经检查的异常,而throwable下的所有其他内容都经过检查。
摘要:如果可以合理地期望客户端从异常中恢复,则将其设为受检异常。如果客户端无法从异常中恢复,请将其设为未经检查的异常。
运行时异常为您提供了避免捕获、声明异常的灵活性。
Exceptions are two types in java:
1. **Checked Exception: The exceptions which are checked by compiler.
例如:我们正在对文件执行操作,然后编译器会要求您通过 try-catch 块或 throws 关键字来处理 IOException。
2. Unchecked Exception: The exceptions which are not checked by compiler at run time.
例如:如果您正在对对象执行操作而不创建它;在这种情况下,您将得到 NullPointerException。