运行时/已检查/未检查/错误/异常之间的差异
Posted
技术标签:
【中文标题】运行时/已检查/未检查/错误/异常之间的差异【英文标题】:Differences between Runtime/Checked/Unchecked/Error/Exception 【发布时间】:2011-03-10 22:01:24 【问题描述】:什么是运行时异常,什么是检查/未检查异常以及错误/异常之间的区别。为什么有这么多类型?相反,Java 可能只是遵循一个简单的设计(只是尝试/捕获所有类型)来处理程序中的异常情况?
【问题讨论】:
你读过Sun Java Tutorials lesson on exceptions吗?这可能是一个不错的起点。 【参考方案1】:由于我是一名新的Java开发人员,我在区分和处理不同类型的异常方面也遇到了一些困难。这就是为什么我在这个主题上做了一个简短的笔记,每当我感到困惑时,我都会仔细阅读。这是Throwable
类层次结构的图像:
[图片由JavaTpoint提供]。
这里需要记住三个关键类:Throwable
、Exception
和 Error
。在这些类中Exception
可以分为两种:“Checked Exception”和“Unchecked Exception”。
检查异常:
这些是扩展Throwable
的类,RuntimeException
和 Error
除外。
它们也被称为编译时异常,因为它们在编译时被检查,这意味着编译器强迫我们要么用try/catch
处理它们,要么在函数签名中指出它throws
它们并强迫我们处理它们在调用者中。
它们是由代码无法控制的意外情况(例如数据库关闭、文件 I/O 错误、错误输入等)导致的可通过编程恢复的问题。
示例: IOException
、SQLException
等
未经检查的异常:
扩展RuntimeException
的类称为未经检查的异常。
未检查的异常不在编译时检查,而是在运行时检查,因此得名。
它们也是可通过编程恢复的问题,但与检查异常不同,它们是由代码流或配置中的错误引起的。
例子:ArithmeticException
,NullPointerException
,ArrayIndexOutOfBoundsException
等
由于它们是编程错误,因此可以通过巧妙/明智的编码来避免它们。例如“除以零”产生ArithmeticException
,可以通过对除数的简单检查来避免。同样,我们可以通过简单地检查引用来避免NullPointerException
:if (object != null)
,甚至使用better techniques。
错误:
Error
是指 try/catch
无法处理的不可恢复的情况。
示例: OutOfMemoryError
、VirtualMachineError
、AssertionError
等
为什么会有这么多类型?
除了Stephen C的回答我想说:
异常处理在 Java 中是一项相对昂贵的操作。 我们不应该将所有异常情况都放在try/catch
块中。过度使用try/catch
s 可能会影响程序性能。
总之,Exception
s 应尽可能以编程方式处理。另一方面,我们无法处理Error
s,因此这些可能是存在多种异常类型的一些逻辑原因。
【讨论】:
+1 为漂亮的图片。旁注:Error
无法捕获并不完全正确。没有人阻止您写try sometching(); catch(Error e)
,但这样做实际上是个坏主意(有关详细信息,请参阅@TofuBeer's answer)。【参考方案2】:
Throwable 位于所有异常的首位。 在 Throwable 下面你有错误和异常。 在 Exception 下面你有 RuntimeException。
Java 有两种类型的异常 - 已检查和未检查。已检查的异常由编译器强制执行(您必须在 throws 子句中声明它们并最终捕获它们)。在 throws 子句中捕获或声明未检查的异常不会被强制执行。
(答案有争议的部分)
Throwable 存在,因此所有异常类型都有一个父级。你永远不应该声明你抛出 Throwable 并且永远不会抓住它(除非你真的真的很清楚自己在做什么)。
存在错误表示运行时环境存在问题,您的程序可能无法从中恢复,例如格式错误的类文件或 VM 内存不足。除非您真的知道自己在做什么,否则不应捕获错误。
异常作为所有非程序员错误的根源存在(有关“异常”,请参阅 RuntimeException),例如由于磁盘已满而无法创建文件。您不应抛出、抛出或捕获异常。如果您必须捕获异常,请确保您知道自己在做什么。
RuntimeException 的存在表示所有程序员错误,例如超出数组末尾或调用空对象上的方法。这些是你应该修复的东西,这样它们就不会抛出异常——这表明你,程序员,搞砸了代码。同样,除非您知道自己在做什么,否则不应该抓住这些。
【讨论】:
【参考方案3】:TofuBeer's answer 清楚地解释了异常类的含义。
为什么会有这么多类型?相反,Java 可能只是遵循简单的设计(只是尝试/捕获所有类型)来处理程序中的异常情况?
为什么?因为它们是必需的!如果没有这 4 个类,按大类处理异常是不切实际的。
如果没有Error
类,您将如何捕获“所有致命的 JVM 错误”?
如果没有 Exception
类,您将如何捕获“所有不是 JVM 致命错误的异常”?
如果没有 RuntimeException
类,您将如何捕获“所有未经检查的异常”?
【讨论】:
【参考方案4】: 错误(由 VM 引发,不应被捕获或处理)-
虚拟机错误
断言错误
链接错误...等等
-
NullPointerException
ArrayIndexOutOfBoundException
IllegalArgumentException ... 以此类推
-
IOException
FileNotFoundException
SQLException ...等等
【讨论】:
【参考方案5】:Checked 和 unchecked 异常的区别:
已检查异常和未检查异常之间存在许多差异,但所有差异都源于一个基本考虑,即异常是否可以由编译器解决。
要记住的要点是:
[1] 检查异常意味着编译器检查异常。这意味着编译器要求此类异常由 try-catch 块或 throws 关键字处理。
[2] 未经检查的异常是编译器不提供任何授权的异常,因为它们可以由开发人员通过编码/编程来解决,因为控制流是可控的,如 ArithmeticException、NullPointerException ArrayIndexOutOfBoundsException , IllegalArgumentException 等。
我称之为“Exception-Identity-Test”,您可以从 java doc 中获取任何随机异常,然后只问一个问题。 “嘿例外!你能以编程方式解决吗?”
如果异常显示YES,则它是未经检查的异常,因为这可以通过更改代码或解决某些计算错误等来解决。
另一方面,如果异常说 No 那么这是检查异常,因为检查异常控制流超出了我们的代码,例如如果有人更改数据库密码或有人拔掉网络电缆,连接超时(ConnectException)、一些资源未找到(FileNotFoundException、ClassNotFound)、SQLException、InvocatonTargetException等,这些无法通过编程解决
【讨论】:
【参考方案6】:article 以简洁明了的方式总结了 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
块。我已经在下面的程序中演示了throws
的用法。
未经检查的异常:未经检查的异常在编译时不检查。 Error
和 RuntimeException
类下的 Java 异常是未经检查的异常,throwable 下的所有其他内容都经过检查。
总结:如果可以合理地预期客户端会从异常中恢复,请将其设为已检查异常。如果客户端无法从异常中恢复,请将其设为未经检查的异常。
【讨论】:
【参考方案7】:运行时异常为您提供了避免捕获、声明异常的灵活性。
【讨论】:
是的,好像不捕获异常并让它杀死线程是可以接受的解决方案。 生成您自己的RuntimeException
通常被认为是个坏主意®。谨慎行事,而不仅仅是捷径。【参考方案8】:
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。
【讨论】:
以上是关于运行时/已检查/未检查/错误/异常之间的差异的主要内容,如果未能解决你的问题,请参考以下文章