java 自定义运行时异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17967031/
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
Custom RunTime Exceptions
提问by Chan
So this is regarding an interview question I was recently asked. The interviewer started on this by asking me how we create our custom Exceptions. On answering that, he asked me how I'd create a RunTimeExceptions. I said we'd create them in the same way as we would create the checked Exceptions. Just our custom exception would extend from the RunTimeException class. Then he asked in what scenarios would you create your own RunTimeException. Now I couldn't think of a good answer to that. In none of my projects, we created custom RunTimeExceptions.
所以这是关于我最近被问到的一个面试问题。面试官首先问我我们如何创建自定义异常。在回答这个问题时,他问我如何创建 RunTimeExceptions。我说过我们会以与创建受检异常相同的方式创建它们。只是我们的自定义异常将从 RunTimeException 类扩展。然后他问你会在什么情况下创建自己的 RunTimeException。现在我想不出一个好的答案。在我的所有项目中,我们都没有创建自定义 RunTimeExceptions。
I also think that we should never create RunTimeExceptions. JVM can fail only in a finite number of ways and it handles them well. While writing an application we can't predict what runtime exceptions can occur and hence we shouldn't need to handle them. And if we can predict those conditions, they aren't RunTimeExceptions then. Since we neither need new runtime exceptions, nor need a handling of runtimeexceptions, why would we ever need to create a custom RunTimeException. Everything that we can pre-think of as a possible failure condition should be handled at compile time and it would be a checked exception. Right? Only the things that cannot be handled at compile time and the ones that depend on run time things go into the category of RunTimeExceptions.
我还认为我们永远不应该创建 RunTimeExceptions。JVM 只能以有限的几种方式失败,并且可以很好地处理它们。在编写应用程序时,我们无法预测会发生什么运行时异常,因此我们不需要处理它们。如果我们可以预测这些条件,那么它们就不是 RunTimeExceptions。既然我们既不需要新的运行时异常,也不需要处理运行时异常,为什么我们需要创建自定义的 RunTimeException。我们可以预先考虑的所有可能的失败条件都应该在编译时处理,这将是一个已检查的异常。对?只有在编译时无法处理的事物和依赖于运行时事物的事物进入 RunTimeExceptions 的类别。
Even if we write custom RunTimeExceptions and then a custom method that should throw that RunTimeException - how do we make sure that the method will throw that particular RunTimeException. How do we do that mapping. It doesn't seem possible to me.
即使我们编写了自定义 RunTimeExceptions,然后编写了一个应该抛出该 RunTimeException 的自定义方法 - 我们如何确保该方法会抛出该特定的 RunTimeException。我们如何进行映射。对我来说似乎不可能。
Am I missing something/ many things here? Kindly advice.
我在这里错过了什么/很多东西吗?友善的建议。
Thanks, Chan.
谢谢,陈。
回答by dasblinkenlight
I think the interviewer was trying to see if you understand the purpose of runtime exceptions, which is to signal programmer's errors (as opposed to application exceptions, which signal problems with the execution environment).
我认为面试官是想看看你是否理解运行时异常的目的,它是向程序员的错误发出信号(与应用程序异常相反,它表示执行环境存在问题)。
You can and you should create subclasses of RuntimeException
whenever your method needs to signal a condition that amounts to a programming error, and you need to provide additional information regarding the error the exception describes.
您可以并且应该RuntimeException
在您的方法需要发出相当于编程错误的条件信号时创建子类,并且您需要提供有关异常描述的错误的附加信息。
For example, consider a class that lets you store data in a sparse multidimensional array. One of the APIs such class would probably provide is a getter that takes an array of indexes. The number of indexes needs to equal the number of dimensions in the array, and each index must be within its bounds. Supplying an array parameter that has an incorrect number of elements, or has one or more element outside its bounds, is a programming error. You need to signal it with a runtime exception. If you want to signal this error, and provide a full account of what went wrong, your subclass IllegalArgumentException
, a subclass of RuntimeException
, to build your own exception.
例如,考虑一个让您将数据存储在稀疏多维数组中的类。此类类可能提供的 API 之一是采用索引数组的 getter。索引的数量需要等于数组的维数,并且每个索引都必须在其范围内。提供的数组参数的元素数量不正确,或者有一个或多个元素超出其边界,是一种编程错误。您需要使用运行时异常向它发出信号。如果您想发出此错误信号,并提供错误的完整说明,您的子类IllegalArgumentException
,即 的子类RuntimeException
,来构建您自己的异常。
Finally, there is one more situation when you want to subclass RuntimeException
: when you should provide a "regular" exception, but you do not want your users to wrap each call of your API in a try
/catch
block. In situations like these, you can replace a single method
最后,当您想要子类化RuntimeException
时,还有另一种情况:您应该提供“常规”异常,但您不希望您的用户将 API 的每个调用都包装在try
/catch
块中。在这种情况下,您可以替换单个方法
void performOperation() throws CustomApplicationException;
with a pair of methods
用一对方法
boolean canPerformOperation();
void performOperation();
The first method tells the caller that it is safe to call the second method in the current state; it never throws an exception.
第一个方法告诉调用者在当前状态下调用第二个方法是安全的;它从不抛出异常。
The second method fail only in the state when the first method returns false
, making a failure a programming error, thus justifying the use of RuntimeException
to signal such failures.
第二种方法仅在第一种方法返回的状态下失败false
,使失败成为编程错误,从而证明使用RuntimeException
来发出此类失败的信号是合理的。
回答by Hoàng Long
Checked Exception vs Unchecked Exception is a long time debate among Java developers. I'm not be here to ignite the fire, but only want to share with you how I use it in our work.
已检查异常与未检查异常是 Java 开发人员之间长期存在的争论。我不是来点火的,只是想和大家分享一下我在工作中是如何使用它的。
For example, another service call my server for customer information. The input is customerID, and I will return a customer object
例如,另一项服务呼叫我的服务器以获取客户信息。输入的是customerID,我会返回一个customer对象
// Web Service interface
public CustomerInfo getCustomerInformation(int customerId, int securityToken) {
check(securityToken);
Customer customer = merchantService.getCustomer(customerId);
return customer.getInfo();
}
// MerchantService
public Customer getCustomer(int customerId) {
return customerService.getCustomer(customerId);
}
What will happen if the system can't find a particular customer? Of course it will throw an exception or return null. But returning null is bad, since it will make you check null everytime calling from a service. So I go with throwing exception:
如果系统找不到特定客户会怎样?当然会抛出异常或者返回null。但是返回 null 是不好的,因为它会让你每次从服务调用时都检查 null。所以我抛出异常:
// Customer service
public Customer getCustomer(id) {
Customer customer = getCustomerFromDB();
if (customer == null) throw CustomerNotExistedException();
return customer;
}
Now the question is whether CustomerNotExistedException is a Exception or a RuntimeException. If it's a checked exception, you will need to catch and process it at the function that calls getCustomer
. That means you must catch it at MerchantService. However, all you want is to produce a 404 error at WebService level, so that catching it at MerchantService won't do anything more than throwing the exception again. It pollutes the code.
现在的问题是 CustomerNotExistedException 是 Exception 还是 RuntimeException。如果是受检异常,则需要在调用getCustomer
. 这意味着您必须在 MerchantService 上捕获它。但是,您想要的只是在 WebService 级别产生 404 错误,以便在 MerchantService 捕获它只会再次抛出异常。它污染了代码。
In the general case, I often use RuntimeException to let some exception "bubble up" to the level in which they can be processed.
在一般情况下,我经常使用 RuntimeException 来让一些异常“冒泡”到可以处理它们的级别。
For your reference, I would recommend the book Clean code from Robert C. Martin. It explains quite well how we should use exception to handle errors in Java.
作为您的参考,我会推荐Robert C. Martin的书Clean code。它很好地解释了我们应该如何使用异常来处理 Java 中的错误。
回答by Jon Skeet
You would create your own RuntimeException
subclass if:
如果出现以下情况,您将创建自己的RuntimeException
子类:
- You don't want it to be a checked exception, because you don't expect callers to explicitly catch the exception. (Personally I believe that checked exceptions are rather overused in the standard library.)
- You still want to provide more information than just a message (just the type itself is a helpful starting point in a log).
- 您不希望它成为已检查的异常,因为您不希望调用者显式捕获异常。(我个人认为检查异常在标准库中被过度使用了。)
- 您仍然希望提供更多信息而不仅仅是一条消息(只是类型本身是日志中一个有用的起点)。
HibernateException
is an example of this in the Hibernate ORM.
HibernateException
是 Hibernate ORM 中的一个示例。
回答by NINCOMPOOP
I think when you are creating Custom Exceptions , please don't subclass RuntimeException
, it defeats the whole purpose of creating the custom exception.
我认为当您创建自定义异常时,请不要子类化RuntimeException
,它违背了创建自定义异常的全部目的。
Even if we write custom RunTimeExceptions and then a custom method that should throw that RunTimeException - how do we make sure that the method will throw that particular RunTimeException.
即使我们编写了自定义 RunTimeExceptions,然后编写了一个应该抛出该 RunTimeException 的自定义方法 - 我们如何确保该方法会抛出该特定的 RunTimeException。
The point here is actually the caller of the method needn't surround that in a try-catch
block as it is not a checked exception. Unless you have a good reason to throw a custom unchecked exception , say , just to provide additional custom information for logging etc. don't do that. Another bad implementation will be sometimes you would to just want to catch the checked exceptions in your code and throw custom unchecked exceptions to get rid of all the try-catch in the caller code.
这里的重点实际上是方法的调用者不需要将它包含在try-catch
块中,因为它不是已检查的异常。除非您有充分的理由抛出自定义的未经检查的异常,例如,只是为日志记录等提供额外的自定义信息,否则不要这样做。另一个糟糕的实现是有时您只想捕获代码中的已检查异常并抛出自定义的未检查异常以摆脱调用者代码中的所有 try-catch。