简体   繁体   English

是在代码中检查异常还是在Java中使用try-catch更好的做法?

[英]Is checking for exceptions in code or using try-catch a better practice in Java?

I had someone mention to me that catching all exceptions is not necessarily good practice (for example, NullPointerException). 我有人向我提到,捕获所有异常并不一定是好习惯(例如,NullPointerException)。 I am looking for an explanation of when this is a good thing, when it is not, and why it is as such :D 我正在寻找一个解释,这是什么时候这是一件好事,什么时候不是,为什么它是这样的:D

Thanks!! 谢谢!!

badPanda badPanda

In short: 简而言之:

Checked exceptions are for catching 检查异常是为了捕获

Unchecked exceptions and errors can be left to bubble up. 未经检查的异常和错误可能会冒泡。 (these are the subclasses of RuntimeException and Error ). (这些是RuntimeExceptionError的子类)。

This is because checked exceptions are "expected" and the program can recover from them. 这是因为已检查的异常是“预期的”,程序可以从中恢复。 Unchecked exceptions are such from which the program cannot recover (easily). 未经检查的异常是程序无法恢复的(容易)。

Sun's tutorial says (it's about deciding what kind of exception you should create, but it is also informative on the other side - ie when using exceptions): Sun的教程说(它是关于决定你应该创建什么样的异常,但它在另一方面也提供了信息 - 即使用异常时):

Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. 这是底线指南:如果可以合理地期望客户端从异常中恢复,则将其作为已检查的异常。 If a client cannot do anything to recover from the exception, make it an unchecked exception. 如果客户端无法执行任何操作以从异常中恢复,请将其设置为未经检查的异常。

To further Bozho's post checked exceptions typically handle exceptions you expect to happen regardless of how perfect your code is (ie: a network cable is unplugged and you catch and IO exception). 进一步Bozho的post检查异常通常会处理您希望发生的异常,无论您的代码有多完美(例如:网络电缆已拔出,您捕获和IO异常)。 You declare they methods throw checked exceptions as other code must deal with how to handle these exceptions. 您声明它们的方法抛出已检查的异常,因为其他代码必须处理如何处理这些异常。

Unchecked exceptions tend to be used for unexpected conditions for example NullPointerExceptions often bubble up because the program should have thrown a checked exception, filtered data, set defaults, etc. They are unchecked and often unexpected, thus you do not have to catch them. 未经检查的异常往往用于意外情况,例如NullPointerExceptions经常冒出来,因为程序应该抛出已检查的异常,过滤的数据,设置默认值等。它们是未经检查的并且通常是意外的,因此您不必捕获它们。

This is not true 100% of the time but as a general approach that is how it works, in Java especially. 这在100%的情况下并非如此,但作为一种通用的方法,它在Java中尤其如此。

并且添加到bozho的答案中,它有时也取决于应用程序的类型,因为在某些情况下,您可能必须处理它以执行某些操作,并且在某些情况下,您可以让它由调用者处理或最终终止。

The title of your question seems to ask if it's better to check for and handle error conditions in the code or if it's better to just put it all in a try block and deal with exceptions in a catch. 您的问题的标题似乎在询问是否更好地检查并处理代码中的错误条件,或者最好将它全部放在try块中并处理catch中的异常。

If it's simple, definitely check for an error and deal with it rather than using a try-catch. 如果它很简单,一定要检查错误并处理它而不是使用try-catch。 For example, if you can deal with invalid input by checking it and printing a "please try again" type of message, you wouldn't use a try-catch. 例如,如果您可以通过检查无效输入并打印“请再试”类型的消息来处理无效输入,则不会使用try-catch。

I like to think this way: If I can neatly step around the error introduced by the exception, check for the conditions that would cause it and deal with them. 我喜欢这样思考:如果我可以巧妙地绕过异常引入的错误,请检查导致它的条件并处理它们。 If you wouldn't be able to either easily check for the conditions or easily deal with them, use a try-catch to handle it. 如果您无法轻松检查条件或轻松处理它们,请使用try-catch来处理它。

Exceptions that are not caused by programming errors and/or can be recovered from should be caught. 应该捕获不是由编程错误引起和/或可以从中恢复的异常。 Others should not be. 其他人不应该。 In java generally checked exceptions are supposed to be caught while RunTimeExceptions and Errors are not. 在java中,通常检查异常应该在RunTimeExceptions和Errors不被捕获时被捕获。

A null pointer exception is caused by a programming error ie missing null check so it should not be caught. 空指针异常是由编程错误引起的,即缺少空检查,因此不应该捕获它。 However there might also be situations where you will want to catch a RunTimeException solely for the purpose of logging it before throwing it back. 但是,在某些情况下,您可能希望捕获RunTimeException,仅用于在将其抛回之前进行记录。

RuntimeExceptions can (most of the cases) be considered "programming errors". RuntimeExceptions可以(大多数情况下)被视为“编程错误”。 For example, think of poping an object from a stack before checking if it actually contains any elements. 例如,考虑在检查它是否实际包含任何元素之前从堆栈中弹出一个对象。 In a proper implementation, there should be some isEmpty() method given to check the state of the stack. 在适当的实现中,应该有一些isEmpty()方法来检查堆栈的状态。 If the programmer is to lazy or forgets to check the stack, an exception should be thrown to indicate a programming error. 如果程序员懒惰或忘记检查堆栈,则应抛出异常以指示编程错误。

These kinds of exceptions should NOT be caught. 不应该抓住这些例外。 The idea is to crash the program and inform the programmer of his mistake. 这个想法是让程序崩溃并告诉程序员他的错误。

Checked exceptions on the other hand, as others have stated, are exceptions from which the programs is expected to recover from. 另一方面,检查异常,正如其他人所说,是预期程序可以从中恢复的例外情况。 While this sounds like a good idea in practice, checked exceptions are often thrown when you can't really do anything to solve the cause of the exception. 虽然这在实践中听起来是个好主意,但是当您无法真正做任何事情来解决异常原因时,通常会抛出检查异常。 So you end up with lots of boilerplate code (ie try-catch-blocks, whose exception blocks do nothing but logging or printing the cause of the exception). 因此,您最终会得到许多样板代码(即try-catch-blocks,其异常块除了记录或打印异常原因外什么都不做)。 Afaik, no newer programming language supports checked exceptions because of this (even JavaFX). Afaik,没有新的编程语言因此支持检查异常(甚至是JavaFX)。

I always implement a try...catch(Throwable) (a Throwable is truly an error and your application should not perform any further operations after it get one of those) at ONE point in my code, when it is extremely important to know what happened so it can be logged. 我总是实现一个try...catch(Throwable) (一个Throwable真的是一个错误,你的应用程序在获得其中一个之后不应该执行任何进一步的操作)在我的代码中的一个点,当知道什么是非常重要的发生这样就可以记录下来。 That place is usually the main method. 那个地方通常是main方法。

I also have try...catch(Exception) in a runnable class, or a class that process, for example, one record that can be processed independently of others. 我还尝试在runnable类中捕获(异常),或者处理一个类,例如,一个可以独立于其他记录处理的记录。 In that case, the application should move on even if part of its processing fail - it doesn't matter if I know what exception is going to be thrown or not - I catch the exception, I log it, I abort that processing entry, and I move on. 在这种情况下,即使部分处理失败,应用程序仍应继续运行 - 如果我知道将抛出什么异常并不重要 - 我捕获异常,我记录它,我中止该处理条目,然后继续前进

The rule of thumb is that you should catch an exception if you are going to do something about it (either abort the processing of something, run an alternative routine, or move on, as long as you know what you are doing), if you are not going to do something about it, don't catch it. 经验法则是,如果你要对它采取一些措施,你应该抓住一个例外(如果你知道你在做什么的话,要么中止某事的处理,运行另一个例程,要么继续前进),如果你不打算对此采取行动,不要抓住它。

And don't use your IDE try...catch creator to hide your exception, instead let it add the exceptions to the method signature. 并且不要使用您的IDE try...catch创建器来隐藏您的异常,而是让它为方法签名添加异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM