Java/C#中检查的异常是什么?

bli*_*egz 27 c# java exception

我是一名C#开发人员,偶尔用Java编写代码.有人可以用简单的术语解释Java中检查的异常是什么以及为什么需要它?没有在C#中遇到过这个术语.

Mat*_*hen 57

已检查的异常是编译器要求您以某种方式处理的异常.

在Java中,checked异常是ThrowableS中的不是RuntimeException,Error或它们的一个子类.

Java设计者认为他们需要确保程序处理合理可能的异常.一个典型的例子是IOException.只要程序执行I/O,就有可能出现故障.磁盘可能已满,文件可能不存在,可能存在权限问题等.

因此,Java的设计使得程序必须以某种方式在语法上处理异常.这可能是一个catch块,或者以某种方式重新抛出异常.

C#没有检查异常.他们决定将此问题留给应用程序开发人员(面试).检查的异常是有争议的,因为它们可以使代码冗长,而开发人员有时会使用空的catch块来处理它们.此外,它可以是任意标准库方法抛出已检查的异常.例如,为什么不File.delete(新的Java 7 API以不同方式执行)抛出IOException

Hejlsberg在该访谈中指出的另一个问题是可版本性.向throw子句添加已检查的异常会强制修改和重新编译使用该方法的所有代码.

  • `将一个已检查的异常添加到throw子句会强制修改和重新编译使用该方法的所有代码 - 因此您有未经检查的异常.好吧,除非你认为"在某些情况下会失败"是你想要描述你的API的方式.每个例外都是方法的公共接口的一部分,稍后添加的就像是说"哦,从现在开始,int参数将具有完全不同的语义含义 - 但不要担心,它仍然是二进制兼容的!" (5认同)
  • @Voo,这是在[本部分](http://www.artima.com/intv/handcuffs2.html)的访谈中具体讨论的.Hejlsberg认为并非每个例外实际上都需要由立即调用代码来处理.他说有些最好由主消息处理程序处理,即使主处理程序没有使用新异常的特定知识编写. (3认同)
  • Imo他使用了一个糟糕的库示例.如果我编写一个我希望稍后更改的库,我将不得不让它的方法抛出一个足够抽象的异常(例如,抛出SqlException的一些泛型数据处理程序类明显违反了这个原则).然后,如果我想,我可以稍后添加其他子类,这提供了类似的可能性,但有类似的缺点.所以是的,我同意Java检查过的异常处理有问题(尽管有7个更好的样板代码),[续] (2认同)
  • 但我认为只有未经检查的异常会误导程序员忽略错误情况并对其API进行更改以破坏与早期版本的兼容性.我已经看到了这么多的C#代码来完成这个并且最好地记录抛出的异常我只是觉得这不是更好的方法.另一方面,我看到在过去的几年中几乎没有人在Java中使用`throw Exception` - 我认为这对它有很大的耻辱.但是,我仍然希望有一些解决方案可以让我们减少检查异常所需的样板,而不会出现未经检查的异常. (2认同)

Fri*_*z H 6

在Java中,检查异常(正如Matthew Flaschen正确指出的那样)是编译器要求您处理的异常.这些是在函数定义上声明的异常(例如function bob() throws ImNotBobException { ... },调用该函数可能抛出该异常 - 例如,NumberFormatException在解析整数时,或者IOException在写入文件时).

但是,某些异常可能会从未知或意外的位置抛出,这些位置在每个级别上处理都是不切实际的,因此编译器不需要您处理这些异常.这些是未经检查的例外情况.它们可以从不声明抛出它们的各个地方抛出(通常是在该对象尚未初始化时尝试调用对象上的方法,即为null - 这将导致a NullPointerException.)

希望这可以帮助.