Java 自定义运行时异常

Java 自定义运行时异常,java,custom-exceptions,Java,Custom Exceptions,这是关于我最近被问到的一个面试问题。面试官首先问我如何创建自定义异常。在回答这个问题时,他问我如何创建RunTimeExceptions。我说过我们将以创建选中异常的相同方式创建它们。我们的自定义异常将从RunTimeException类扩展而来。然后他问在什么情况下您会创建自己的RunTimeException。现在我想不出一个好的答案。在我的所有项目中,我们都没有创建自定义运行时异常 我还认为我们不应该创建运行时异常。JVM只能以有限的方式失败,而且它处理得很好。在编写应用程序时,我们无法预

这是关于我最近被问到的一个面试问题。面试官首先问我如何创建自定义异常。在回答这个问题时,他问我如何创建RunTimeExceptions。我说过我们将以创建选中异常的相同方式创建它们。我们的自定义异常将从RunTimeException类扩展而来。然后他问在什么情况下您会创建自己的RunTimeException。现在我想不出一个好的答案。在我的所有项目中,我们都没有创建自定义运行时异常

我还认为我们不应该创建运行时异常。JVM只能以有限的方式失败,而且它处理得很好。在编写应用程序时,我们无法预测可能发生的运行时异常,因此不需要处理它们。如果我们能够预测这些条件,那么它们就不是运行时异常。既然我们既不需要新的运行时异常,也不需要对运行时异常进行处理,那么为什么我们需要创建自定义的运行时异常呢。我们可以预先认为是可能的故障条件的所有内容都应该在编译时处理,这将是一个已检查的异常。对吗?只有编译时无法处理的事情和依赖于运行时的事情才属于运行时异常的范畴

即使我们编写自定义RunTimeException,然后编写一个应该抛出该RunTimeException的自定义方法,我们如何确保该方法将抛出该特定RunTimeException。我们如何进行映射。在我看来这是不可能的

我在这里遗漏了什么/很多东西吗?好心的建议

谢谢,
Chan.

我认为当您创建自定义异常时,请不要将
RuntimeException子类化,它会破坏创建自定义异常的整个目的

即使我们编写自定义RunTimeException,然后编写一个应该抛出该RunTimeException的自定义方法,我们如何确保该方法将抛出该特定RunTimeException


这里的要点实际上是方法的调用者不需要在
try-catch
块中包围它,因为它不是一个选中的异常。除非你有一个很好的理由抛出一个自定义的未检查异常,比如说,只是为了提供额外的自定义信息来记录日志等等,否则不要这样做。另一个糟糕的实现是,有时您只想捕获代码中的已检查异常,并抛出自定义的未检查异常,以消除调用方代码中的所有try-catch。

如果出现以下情况,您将创建自己的
RuntimeException
子类:

  • 您不希望它是已检查的异常,因为您不希望调用方显式捕获该异常。(我个人认为,在标准库中,选中的异常被过度使用。)
  • 您仍然希望提供更多的信息,而不仅仅是消息(只有类型本身才是日志中有用的起点)

是Hibernate ORM中的一个例子。

我想采访者是想看看你是否理解运行时异常的目的,它是为了表示程序员的错误(而不是应用程序异常,它表示执行环境有问题)

每当您的方法需要发出相当于编程错误的条件的信号时,您可以并且应该创建
RuntimeException
的子类,并且您需要提供有关异常描述的错误的附加信息

例如,考虑一个允许在稀疏多维数组中存储数据的类。此类可能提供的API之一是获取索引数组的getter。索引的数量必须等于数组中的维度数量,并且每个索引必须在其边界内。提供的数组参数的元素数不正确,或者有一个或多个元素超出其边界,这是编程错误。您需要向它发送运行时异常信号。如果您想发出此错误的信号,并提供出错原因的完整说明,您的子类

IllegalArgumentException
,一个
RuntimeException
的子类,用于构建您自己的异常

最后,还有一种情况是,您希望将
RuntimeException
子类化:您应该提供一个“常规”异常,但不希望用户将API的每个调用包装在
try
/
catch
块中。在这种情况下,可以替换单个方法

void performOperation() throws CustomApplicationException;
用两种方法

boolean canPerformOperation();
void performOperation();
第一个方法告诉调用方在当前状态下调用第二个方法是安全的;它从不抛出异常


第二个方法只有在第一个方法返回
false
时才会失败,使失败成为编程错误,从而证明使用
RuntimeException
来表示此类失败是合理的。

检查异常与未检查异常是Java开发人员长期争论的问题。我不是来这里点火的,只是想和大家分享我是如何在我们的工作中使用它的

例如,另一个服务呼叫我的服务器以获取客户信息。输入是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);
}
如果系统找不到特定客户,会发生什么?当然,它将抛出异常或返回null。但是返回null是不好的,因为它会使您在每次从服务调用时都检查null。因此,我提出了一个例外:

// Customer service
public Customer getCustomer(id) {
   Customer customer = getCustomerFromDB();
   if (customer == null) throw CustomerNotExistedException();
   return customer;
}
现在的问题是CustomerNotExistedException是异常还是RuntimeException。如果它是选中的异常,则需要在调用
getCustomer
的函数中捕获并处理它。这意味着你必须在MerchantService抓住它。但是,您只需要在WebService级别生成404错误,这样在MerchantService中捕获该错误只会再次抛出异常。它污染了代码。