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

C# Java/C中的检查异常是什么?,c#,java,exception,C#,Java,Exception,我是一名C#开发人员,偶尔用Java编写代码。有人能简单地解释一下Java中什么是检查异常以及为什么需要它吗?在C#中没有遇到这个术语。检查异常是编译器要求您以某种方式处理的异常 在Java中,选中的异常是非选中的异常或它们的子类之一 Java设计人员认为需要他们来确保程序处理合理可能的异常。一个典型的例子是。每当一个程序执行I/O操作时,都有失败的可能性。磁盘可能已满,文件可能不存在,可能存在权限问题,等等 因此,Java的设计使得程序必须以某种方式在语法上处理异常。这可以通过catch块实现

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

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

在Java中,选中的异常是非选中的异常或它们的子类之一

Java设计人员认为需要他们来确保程序处理合理可能的异常。一个典型的例子是。每当一个程序执行I/O操作时,都有失败的可能性。磁盘可能已满,文件可能不存在,可能存在权限问题,等等

因此,Java的设计使得程序必须以某种方式在语法上处理异常。这可以通过catch块实现,也可以通过某种方式重新触发异常

C#没有已检查的异常。他们决定将这个问题留给应用程序开发人员解决()。检查异常是有争议的,因为它们会使代码变得冗长,而开发人员有时会用空的catch块来处理它们。此外,标准库方法抛出选中的异常可能是任意的。例如,为什么(一个新的Java7API不这样做)抛出
IOException


Hejlsberg在采访中提到的另一个问题是版本性。将选中的异常添加到
throw
子句将强制修改和重新编译使用该方法的所有代码。

选中的异常是要求任何“消费”类必须编写明确检查(并希望处理)异常的代码的异常

例如,如果Apple类有一个Eat()方法,其中包含WormFound的checked异常,那么调用该方法的任何代码都需要显式地捕获该异常

作为旁注,它是Java的特性,而不是C#


(在创建C#时,检查异常的优点在C#团队眼中并不明显,因此它们没有被包括在内。)

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

但是,有些异常可以从未知或意外的位置抛出,而这些位置在每个级别上都无法处理,因此编译器不要求您处理这些异常。这些异常是未经检查的异常。它们可以从未声明要抛出它们的各个位置抛出(通常是在对象尚未初始化时尝试调用该对象上的方法,即为null-这将导致
NullPointerException

希望这能有所帮助。

(几年后,通过谷歌航空公司抵达这里的人)

选中的异常是Java语言.PERIOD设计中的一个错误。每当您发现选中的异常时,都会将它们包装为未选中的异常(可能是RuntimeException)

不幸的是,由于市场问题,先是Sun,然后是Oracle无法公开承认他们的错误

在创建Java时,异常的处理并不清楚。Java设计师天真地认为,强迫开发人员在编译时检查异常是一个好主意。虽然这看起来直观上是正确的,但这变成了一种反模式,类似于使用“GOTOs”。它在实践中从未起作用,并导致许多问题。异常必须在“主循环”或“控制器”中处理,否则,如果它们能够在引发错误的函数内部处理,它们将不是异常,而是正常API返回值必须支持的预期错误。异常本身就是未预期的,不允许正常的代码流执行

例如,请注意,Spring是企业应用程序开发的“标准”Java框架,它仅限于将已检查的异常包装为未检查的异常


作为参考:Kotlin,由Java和Scala专家开发,是中最受欢迎的语言之一),完全删除了检查过的异常。更多信息请访问:

将检查过的异常添加到throw子句将强制修改和重新编译使用该方法的所有代码
-因此您有未检查过的异常。除非您认为
在某些情况下会失败
是您描述API的方式。有没有Y异常是方法的公共接口的一部分,稍后添加异常就像说“哦,从现在起,int参数将具有完全不同的语义含义-但别担心,它仍然是二进制兼容的!”@Voo,这一点在采访的最后一部分中有专门讨论。Hejlsberg认为,并非所有异常都需要立即调用代码来处理。他说,有些异常最好由主消息处理程序来处理,即使主消息处理程序没有使用新异常的特定知识编写。在我看来,他使用了一个糟糕的库示例。如果我编写一个我希望以后更改的库,我必须让它的方法抛出一个足够抽象的异常(例如一些抛出SqlException的泛型datahandler类显然违反了这一原则)。然后,如果我愿意,我可以在以后添加其他子类,这提供了类似的可能性,但也有类似的缺点。因此,是的,我同意Java的检查异常处理存在问题(尽管使用7 wrt到样板代码更好),[cont]但我认为只有未经检查的异常才会误导程序员忽略错误案例,并对其API进行更改,从而破坏与早期版本的兼容性