java 为什么我们不必将 try-catch 添加到 RuntimeException?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2750638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:40:25  来源:igfitidea点击:

Why we don't have to add try-catch to a RuntimeException?

javaexception

提问by Mohamad Alhamoud

I want to ask why we don't have to add try-catch block to a RuntimeExceptionwhile we should do that with other exceptions?

我想问一下为什么我们不必将 try-catch 块添加到RuntimeExceptionwhile 我们应该在其他例外情况下这样做?

I mean like :

我的意思是:

public class Main {
    public static void main(String[] args) {
       throw new RuntimeException();
    }
}

Edit : when I say : throw new RuntimeException();it is so clear that there is an exception will happen ,so why the compiler doesn't forbid that ?

编辑:当我说:throw new RuntimeException();很明显会发生异常,那么为什么编译器不禁止呢?

回答by BalusC

That's because it's an uncheckedexception. It doesn't need to be explicitly declared or catched. Also see the Sun tutorial on the subject.

那是因为它是一个未经检查的异常。它不需要显式声明或捕获。另请参阅有关该主题Sun 教程

Update:in general, you should only throw a RuntimeException(preferably one of its subclasseslisted in the javadoc) to signal that the caller is doing it wrong. I.e. passing a nullargument (then throw NullPointerException), or an illegal argument (then throw IllegalArgumentException), or the method is called at the wrong moment/state (then throw IllegalStateException), etcetera. The caller is supposed to fix their code to avoid that. E.g. checking beforehand if the argument is not null, or if the argument is in correct format/syntax, or ensuring that the method is called at the right moment.

更新:一般来说,您应该只抛出一个RuntimeException(最好是 javadoc 中列出的它的子类之一)来表示调用者做错了。即传递null参数(然后 throw NullPointerException),或非法参数(然后 throw IllegalArgumentException),或者在错误的时刻/状态(然后 throw IllegalStateException)调用该方法,等等。调用者应该修复他们的代码以避免这种情况。例如,事先检查参数是否不为空,或者参数是否采用正确的格式/语法,或者确保在正确的时刻调用该方法。

If there is a specific situation which should throw a runtime exception and you can't use one of its specific subclasses, then you are supposed to extend it and document it properly in the new exception's javadoc and in the calling method, e.g. ConfigurationException extends RuntimeExceptionfor the case that the calling code hasn't configured the application/API properly before use. This should signal the enduser (the other developer) sufficiently to take action accordingly.

如果存在应该抛出运行时异常并且您不能使用其特定子类之一的特定情况,那么您应该扩展它并在新异常的 javadoc 和调用方法中正确记录它,例如ConfigurationException extends RuntimeException对于这种情况调用代码在使用前没有正确配置应用程序/API。这应该向最终用户(其他开发人员)发出足够的信号,以采取相应的行动。

In nutshell: RuntimeExceptionsshould identify programmatically recoverable problems which are caused by faults in code flow or configuration (read: developer's faults). Checked Exceptionsshould identify programmatically recoverable problems which are caused by unexpected conditions outside control of code (e.g. database down, file I/O error, wrong enduser input, etc). Errorsshould identify programmatically unrecoverable problems (e.g. out of memory, exception inside an initializer, etc).

简而言之:RuntimeExceptions应该识别由代码流或配置中的错误引起的可通过编程恢复的问题(阅读:开发人员的错误)。CheckedExceptions应识别由代码控制之外的意外情况(例如数据库关闭、文件 I/O 错误、最终用户输入错误等)引起的可通过编程恢复的问题。Errors应该识别以编程方式无法恢复的问题(例如内存不足、初始化程序中的异常等)。

回答by bragboy

Lets argue this way. What if NullPointerException was designed to be a compile time exception? Had it been done so, the compiler had to strictly check whether a variable is null or not. There is no way that this can be done.

让我们这样争论。如果 NullPointerException 被设计为编译时异常怎么办?如果这样做,编译器必须严格检查变量是否为空。没有办法做到这一点。

public void dummyMethod(Object obj){

}

Here there is no way for the compiler to check whether the obj can be null or not. However, there has to be some error/exception has to be thrown when you have a null pointer scenario.

这里编译器没有办法检查 obj 是否可以为空。但是,当您遇到空指针场景时,必须抛出一些错误/异常。

回答by mdma

RuntimeException, Errorand their subclasses are specifically not compile-time checked - they are not part of the formal contract of the method.

RuntimeExceptionError并且它们的子类特别不经过编译时检查 - 它们不是该方法的正式合同的一部分。

See Chapter 11 in the JLS, Exceptions, in particular 11.2, Compile-time checking of Exceptions.

请参阅 JLS 中的第 11 章,异常,特别是 11.2,异常的编译时检查。

回答by Pascal Thivent

Per language specification, unchecked exceptionsare not checked at compile-timewhich means that the compiler does not require methods to catch or to specify (with a throws) them. Classes belonging to this category are detailed in the section 11.2 Compile-Time Checking of Exceptionsof the JLS:

每语言规范,检查异常不是在编译时检查,这意味着编译器不要求的方法来捕捉或指定(有throws)他们。属于此类别的类在第11.2节JLS的异常编译时检查中有详细说明:

The unchecked exceptions classesare the class RuntimeExceptionand its subclasses, and the class Errorand its subclasses. All other exception classes are checked exception classes. The Java API defines a number of exception classes, both checked and unchecked. Additional exception classes, both checked and unchecked, may be declared by programmers. See §11.5for a description of the exception class hierarchy and some of the exception classes defined by the Java API and Java virtual machine.

unchecked异常类是类RuntimeException和它的子类,类Error和它的子类。所有其他异常类都是检查异常类。Java API 定义了许多异常类,包括已检查的和未检查的。程序员可以声明额外的异常类,包括检查的和未检查的。有关异常类层次结构和一些由 Java API 和 Java 虚拟机定义的异常类的描述,请参见第11.5 节

So because a RuntimeExceptionin a unchecked exception, the compiler doesn't force you to handle it. If you want to force the caller of a piece of code to handle an exception, use a checked exception (the subclasses of Exceptionother than RuntimeExceptionare all checked exception classes).

因此,因为 aRuntimeException在未经检查的异常中,编译器不会强迫您处理它。如果要强制一段代码的调用者处理异常,就使用受检异常(Exception其他的子类RuntimeException都是受检异常类)。

回答by mickeymoon

Most of the answers on this forum have been talking about the Exception hierarchy and the Java compiler not catching them but I would try to answer this more from the design perspective and why perhaps things were designed like this.

这个论坛上的大多数答案都在谈论异常层次结构和 Java 编译器没有捕捉到它们,但我会尝试从设计的角度更多地回答这个问题,以及为什么事情是这样设计的。

Basically when you call a function(or write some code) an exception can be thrown out of it based on three different situations:

基本上,当您调用一个函数(或编写一些代码)时,可以根据三种不同的情况抛出异常:

  1. Based on an unavoidable conditionlike unavailability of network or some expected file missing on the file system.

  2. Based on an avoidable but known conditionlike Integer.parseInt(String)can throw NumberFormatExceptionif the caller passes a unconvertible string like "Hello", but the caller may ensure proper validations in place before passing in any string to the function and completely do away with the possibility of generating the exception. A common use case could be validating the form field ageon a web page before passing it to deeper layers that make the conversion.

  3. An unknown or unexpected conditionAny time some line of code can throw an exception in your code because there was some mistake that you did and didn't observe the error condition until it blasted off in production, generally happens with NullPointer Reference, IndexOutOfBoundsetc, which if observed would possibly fall in category 2.

  1. 基于不可避免的情况,例如网络不可用或文件系统上缺少某些预期文件。

  2. 基于一个可避免但已知的条件,例如如果调用者传递一个Integer.parseInt(String)不可NumberFormatException转换的字符串(如 )"Hello",则可能会抛出,但调用者可以确保在将任何字符串传递给函数之前进行适当的验证,并完全消除生成异常的可能性。一个常见的用例可能是验证age网页上的表单字段,然后再将其传递给进行转换的更深层次。

  3. 一个未知的或意外的情况任何时候的一些代码行可以在你的代码,因为有一些错误,你这样做,直到它在生产升空并没有观察到错误条件抛出一个异常,一般与发生NullPointer ReferenceIndexOutOfBounds等等,而如果观察可能属于第 2 类。

Exceptions of category 1 are generally designed as Checked Exceptionsbecause it needs to enforce the check for unavoidable error conditions, and to enforce their fallbacks. For examples IOException is checked exception, because in case you are opening a file, there can be a lot many things that may go wrong(like file may be deleted, permissions etc.)and pre validating all of them can be very cumbersome.

类别 1 的异常通常被设计为Checked Exceptions因为它需要强制检查不可避免的错误条件,并强制执行它们的回退。例如 IOException 是检查异常,因为如果您正在打开文件,可能会出现很多错误(例如文件可能被删除,权限等)并且预验证所有这些可能非常麻烦。

Exceptions of the 2nd type are generally modeled as Unchecked Exceptionsbecause you might have your pre validation in place and it might be irritating to be forced to use try and catch for situations that you have already have taken care of.

第二种类型的异常通常被建模为Unchecked Exceptions因为您可能已经进行了预验证,并且在您已经处理过的情况下被迫使用 try 和 catch 可能会令人恼火。

Exceptions of the 3rd type need not be even worried about generally because you cannot put error handling in each and every statement of application code that can unexpectedly come up. But sometimes you can place a global handler, somewhere quite up in the call stack from where almost all the application code gets executed and handle it in a generic manner so that your application does not crash due to an unexpected error.

第 3 种类型的异常通常甚至不必担心,因为您无法在可能意外出现的应用程序代码的每条语句中都放置错误处理。但有时您可以将全局处理程序放置在调用堆栈中的某个位置,几乎所有应用程序代码都从这里执行,并以通用方式处理它,这样您的应用程序就不会因意外错误而崩溃。

For example, if you're running a web application you can configure your Servlet Container to send out a generic 500 Internal Server Errorfor any unhandled error in your application. Or, if you're running a standalone Java application you can keep the contents of your main methodin a try catchblock to prevent crashing the application.

例如,如果您正在运行一个 Web 应用程序,您可以配置您的 Servlet 容器以500 Internal Server Error针对应用程序中任何未处理的错误发送一个泛型。或者,如果您正在运行一个独立的 Java 应用程序,您可以将您的内容保存main method在一个try catch块中以防止应用程序崩溃。

回答by eljenso

Because it's not forbidden to throw runtime exceptions and you don't have to declare runtime exceptions. Your program is a valid Java program so the compiler has no reason to complain.

因为不禁止抛出运行时异常,也不必声明运行时异常。您的程序是有效的 Java 程序,因此编译器没有理由抱怨。

回答by aaaaaaaaaaaa

Basically an uncaught exception is just shorthand for displaying a message and terminating the application.

基本上,未捕获的异常只是显示消息和终止应用程序的简写。

Why would you need to do that? In some cases you can detect that something has gone wrong, some file didn't load, an api is missing, some data is for some reason corrupted, or one of a million other things is wrong. If you don't throw an exception the application may simply crash at another point, or in the worst case, keep running while the error escalates, making it much harder to debug.

为什么你需要这样做?在某些情况下,您可以检测到出现问题、某些文件未加载、API 丢失、某些数据由于某种原因损坏,或者其他一百万件事情中的一件出错了。如果您不抛出异常,应用程序可能会在另一点崩溃,或者在最坏的情况下,在错误升级时继续运行,从而使调试变得更加困难。

It's important to understand that one throws an exception because there is an error, the exception is not the error, it's just the messenger.

理解抛出异常是因为存在错误很重要,异常不是错误,它只是信使。