在 Java 中创建异常的一般经验法则是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26984/
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 10:46:21  来源:igfitidea点击:

What is the general rule of thumbs for creating an Exception in Java?

javaexception

提问by pek

I have been in both situations:

我遇到过两种情况:

  • Creating too many custom Exceptions
  • Using too many general Exception class
  • 创建太多自定义异常
  • 使用太多通用 Exception 类

In both cases the project started OK but soon became an overhead to maintain (and refactor).

在这两种情况下,项目开始时都很好,但很快就变成了维护(和重构)的开销。

So what is the best practice regarding the creation of your own Exception classes?

那么关于创建自己的 Exception 类的最佳实践是什么?

采纳答案by Josh Brown

The Java Specialistswrote a post about Exceptions in Java, and in it they list a few "best practices" for creating Exceptions, summarized below:

The Java Specialists写了一篇关于Java 中的异常的文章,并在其中列出了一些创建异常的“最佳实践”,总结如下:

  • Don't Write Own Exceptions (there are lots of useful Exceptions that are already part of the Java API)

  • Write Useful Exceptions (if you have to write your own Exceptions, make sure they provide useful information about the problem that occurred)

  • 不要编写自己的异常(有很多有用的异常已经是 Java API 的一部分)

  • 编写有用的异常(如果您必须编写自己的异常,请确保它们提供有关所发生问题的有用信息)

回答by Mark Jaeger

Don't do what the developers at my company did. Somebody created an [sic] InvalidArguementException that parallels java.lang.IllegalArgumentException, and we now use it in (literally) hundreds of classes. Both indicate that a method has been passed an illegal or inappropriate argument. Talk about a waste...

不要做我公司的开发人员所做的事情。有人创建了一个 [sic] InvalidArgumentException,它与 java.lang.IllegalArgumentException 平行,我们现在在(字面上)数百个类中使用它。两者都表明一个方法被传递了一个非法或不适当的参数。说废话...

Joshua Bloch covers this in Effective Java Programming Language Guide[my bible of first resort on Best Practices] Chapter 8. ExceptionsItem 42: Favor the use of standard exceptions. Here's a bit of what he says,

Joshua Bloch 在Effective Java Programming Language Guide[我的最佳实践首选圣经]第 8 章 Exceptions Item 42: Favor the use of standard exceptions 中介绍了这一点。这是他说的一些内容,

Reusing preexisting exceptions has several benefits. Chief among these, it makes your API easier to learn and use because it matches established conventions with which programmers are already familiar[my emphasis, not Bloch's]. A close second is that programs using your API are easier to read because they aren't cluttered with unfamiliar exceptions. Finally, fewer exception classes mean a smaller memory footprint and less time spent loading classes.

The most commonly reused exception is IllegalArgumentException. This is generally the exception to throw when the caller passes in an argument whose value is inappropriate. For example, this would be the exception to throw if the caller passed a negative number in a parameter representing the number of times some action were to be repeated.

重用预先存在的异常有几个好处。其中最主要的是,它使您的 API 更易于学习和使用,因为它符合程序员已经熟悉的既定约定[我的重点,而不是 Bloch 的]。紧随其后的是,使用您的 API 的程序更易于阅读,因为它们不会被陌生的异常所困扰。最后,更少的异常类意味着更小的内存占用和更少的加载类所花费的时间。

最常重用的异常是 IllegalArgumentException。这通常是调用者传入值不合适的参数时抛出的异常。例如,如果调用者在参数中传递了一个负数,该参数表示某些操作要重复的次数,则这将是抛出的异常。

That said, you should neverthrow Exception itself. Java has a well-chosen, diverse and well-targeted bunch of built-in exceptions that cover most situations ANDdescribe the exception that occurred well enough so that you can remedy the cause.

也就是说,你永远不应该抛出 Exception 本身。Java 有一组精心挑选、多样化和针对性强的内置异常,它们涵盖了大多数情况并充分描述了发生的异常,以便您可以纠正原因。

Be friendly to the programmers who have to maintain your code in the future.

对将来必须维护您的代码的程序员友好。

回答by Landon Kuhn

My rule of thumb is when the client (the caller) might reasonably want to do something different, depending on the type of exception thrown, the additional exception types are warranted. More often than not, however, the extra exception types are not needed. For instance, if the caller is writing code like

我的经验法则是,当客户端(调用者)可能合理地想要做一些不同的事情时,根据抛出的异常类型,额外的异常类型是有保证的。然而,通常不需要额外的异常类型。例如,如果调用者正在编写类似的代码

try {
     doIt();
} catch (ExceptionType1 ex1) {
     // do something useful
} catch (ExceptionType2 ex2) {
     // do the exact same useful thing that was done in the block above
}

then clearly the additional exception types are not needed. All too often I see (or am forced to write) code like this because the code being called was overzealous in its creation of new exception types.

那么显然不需要额外的异常类型。我经常看到(或被迫编写)这样的代码,因为被调用的代码在创建新的异常类型时过于热情。

回答by jjnguy

If I can't find an exception that has a name describing what type of error was caused then I make my own.

如果我找不到一个异常,它的名称描述了导致什么类型的错误,那么我自己做。

That's my rule-o-thumb.

这是我的经验法则。

回答by Konrad Rudolph

Basically, each job deserves an own exception. When you catch exceptions, you don't distinguish different instances, like you would normally do with objects, therefore you need different subtypes. Using too many custom exceptions is a case which I see hardly occurring.

基本上,每个工作都应该有自己的例外。当您捕获异常时,您不会像通常处理对象那样区分不同的实例,因此您需要不同的子类型。使用太多自定义异常是我认为几乎不会发生的情况。

One advice would be to create exceptions as needed, and if it becomes apparent that one exception type is a duplicate of another, refactor the code by merging the two. Of course it helps if some thought goes into structuring exceptions from the beginning. But generally, use custom exceptions for all cases that have no 1:1 correspondence to existing, situation-specific exceptions.

一个建议是根据需要创建异常,如果一种异常类型与另一种异常类型明显重复,则通过合并两者来重构代码。当然,如果从一开始就考虑构建异常,这会有所帮助。但一般来说,对于与现有的、特定于情况的异常没有 1:1 对应关系的所有情况,请使用自定义异常。

On the other hand, NullPointerExceptions and IndexOutofBoundsExceptions might actually often be appropriate. Don't catch these, though (except for logging) as they're a programming error which means that after throwing them, the program is in an undefined state.

另一方面,NullPointerExceptions 和IndexOutofBoundsExceptions 实际上通常是合适的。但是不要捕捉这些(日志记录除外),因为它们是一个编程错误,这意味着在抛出它们之后,程序处于未定义状态。

回答by shsteimer

My own rule of thumb:

我自己的经验法则:

I never throw Exception, except in unit tests when what you throw is irrelevant and theres no reason to spend any extra time on it.

我从不抛出异常,除非在单元测试中,当你抛出的内容无关紧要并且没有理由在上面花费任何额外的时间。

I create my own custom exception type for errors occuring in my custom business logic. This exception type is used as much as possible for recasting other exceptions, except in cases where it makes sense for the client to have visibility into what actually occurred.

我为自定义业务逻辑中发生的错误创建了自己的自定义异常类型。这种异常类型尽可能多地用于重铸其他异常,除非客户端可以看到实际发生的情况。

回答by Neelesh Salian

While creating your own exception:

在创建自己的异常时:

  • All exceptions must be a child of the Throwable Class

  • If you want to write a checked exception that is automatically enforced by the Handle or Declare Rule, you need to extend the Exception Class

  • If you want to write a runtime execption, you need to extend the Runtime Exception Class.

  • 所有异常都必须是Throwable 类的子

  • 如果要编写由 Handle 或 Declare Rule 自动强制执行的已检查异常,则需要扩展异常类

  • 如果要编写运行时执行,则需要扩展运行时异常类。

回答by Sorter

Don't eat exceptions, throw them https://stackoverflow.com/a/921583/1097600

不要吃异常,抛出它们https://stackoverflow.com/a/921583/1097600

Avoid creating your own exception. Use the below ones that are already there.

避免创建自己的异常。使用以下已经存在的。

IllegalStateException
UnsupportedOperationException
IllegalArgumentException
NoSuchElementException
NullPointerException

Throw unchecked exceptions.

抛出未经检查的异常。

Example

例子

public void validate(MyObject myObjectInstance) {
    if (!myObjectList.contains(myObjectInstance))
        throw new NoSuchElementException("object not present in list");
}