java 抛出异常时的Java最佳实践:抛出核心Java异常

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

Java best practices when throwing exceptions: throwing core Java exceptions

javaexceptionexception-handling

提问by Jon Onstott

Instead of throwing new Exception("Some message", maybeSomeCause), which means that all callers of my method will need to catch Exception (which can include RuntimeExceptions), I'd like to throw a more specific type of exception when a problem occurs.

不是 throwing new Exception("Some message", maybeSomeCause),这意味着我的方法的所有调用者都需要捕获 Exception (可以包括 RuntimeExceptions),我想在出现问题时抛出更具体类型的异常。

I can create my own exception types which extend Exception or another exception type, but I am curious if it is a good idea to re-use some exceptions that come with core Java language, such as:

我可以创建自己的异常类型来扩展 Exception 或其他异常类型,但我很好奇重用核心 Java 语言附带的一些异常是否是个好主意,例如:

  • IllegalArgumentException
  • UnsupportedOperationException
  • IOException
  • Others?
  • 非法参数异常
  • 不支持的操作异常
  • IO异常
  • 其他的?

Are there others that I am missing? I found a basic list of the 'core' exceptions here: http://rymden.nu/exceptions.html, with humous explanations.

还有其他我失踪的吗?我在这里找到了“核心”例外的基本列表:http://rymden.nu/exceptions.html,并附有幽默的解释。

Thanks!

谢谢!

Edit:

编辑:

Is there a good list of 'core' exceptions?

是否有一个很好的“核心”例外清单?

List so far:

到目前为止的清单:

采纳答案by Jeffrey Blattman

Yes, it's very good to do that. In fact, it's even written about in Effective Java, 2nd ed.See item 60 on page 248: "Favor the use of standard exceptions"

是的,这样做很好。事实上,它甚至在Effective Java,第 2 版中有写。请参阅第 248 页上的第 60 条:“支持使用标准例外”

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. A close second is that programs using your API are easier to read because they aren't cluttered with unfamiliar exceptions. Last (and least), fewer exception classes mean a smaller memory footprint and less time spent loading classes.

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

回答by 7yl4r

The lists provided in your question are not very usable as quick-reference material, and most descriptions in the dev docs seem cryptic to me.

您的问题中提供的列表作为快速参考资料不是很实用,而且开发文档中的大多数描述对我来说似乎很神秘。

I haven't run across any short-ish lists of the most reusable built-in exceptions. I've done my best to create one below, but I'm sure it is far from perfect.

我还没有遇到任何最可重用的内置异常的简短列表。我已经尽力在下面创建了一个,但我确信它远非完美。

github gist link(or see current content below)

github gist 链接(或查看下面的当前内容)

List of Potentially Reusable Built-in Exceptions

潜在可重用的内置异常列表

organized by estimated utility

按估计效用组织

IllegalArgumentException

非法参数异常

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

抛出以指示方法已传递非法或不适当的参数。

IndexOutOfBoundsException

索引出界异常

Thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.

抛出以指示某种索引(例如数组、字符串或向量)超出范围。

ArithmeticException

算术异常

Thrown when the requested mathematical operation is non-sensical or impossible. example: int x = 1/0;

当请求的数学运算无意义或不可能时抛出。例如:int x = 1/0;

IllegalStateException

非法状态异常

The application is not in an appropriate state for the requested operation. example: trying to save before file is loaded or created.

应用程序未处于所请求操作的适当状态。例如:尝试在加载或创建文件之前保存。

DataFormatException

数据格式异常

Throw this when you have recieved improperly formatted data. example: MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

当您收到格式不正确的数据时抛出这个。例子:MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

TimeoutException

超时异常

Throw this if something took too long and you're giving up.

如果某件事花费了太长时间而您要放弃,则扔掉它。

KeySelectorException

键选择器异常

I think it makes sense to throw this if you are trying to looking for an object using a key and it was not found or the key is otherwise invalid, but I don't really understand the dev docson it.

我认为如果您尝试使用密钥查找对象但未找到该对象或该密钥无效,则抛出此方法是有意义的,但我并不真正了解其上的开发文档

example: myDataStructure.get("lookup_key");when lookup_keyis not in the data structure.

例如:myDataStructure.get("lookup_key");whenlookup_key不在数据结构中。

IOException

IO异常

Having some problem reading/writing? Throw this exception.

读/写有问题?抛出这个异常。

ScriptException

脚本异常

Running a script of some form and found a problem with it (not I/O or parsing)? Throw this exception.

运行某种形式的脚本并发现它有问题(不是 I/O 或解析)?抛出这个异常。

GeneralSecurityException

一般安全异常

Throw this if you encounter a security-related issue.

如果您遇到与安全相关的问题,请抛出此问题。

RuntimeException

运行时异常

Use this for some runtime-error that doesn't fit well into any other category.

将此用于某些不适合任何其他类别的运行时错误。

回答by Sean Van Gorder

Most core exceptions are too specialized to be used directly, unless you're duplicating existing functionality in the core libs. For instance, you'll probably never need to create an an instance of UnknownHostException; if host resolution fails, the InetAddressor SocketFactorymethod you called would have already created and thrown the exception.

大多数核心异常都过于专业化,无法直接使用,除非您复制核心库中的现有功能。例如,您可能永远不需要创建UnknownHostException;的实例。如果主机解析失败,则您调用的InetAddressorSocketFactory方法将已经创建并抛出异常。

The only exceptions I've found to be generally usable are IOException, IllegalArgumentException, IllegalStateException, and UnsupportedOperationException.

我认为一般可以使用唯一的例外是IOExceptionIllegalArgumentExceptionIllegalStateException,和UnsupportedOperationException

IOException- All problems with interfaces, networking, and hard drive access fall under this. If you're writing code to access external data or hardware, you should be using this. For instance, if you're implementing an API to access a certain type of network device, you can make a MyDeviceExceptionsubclass to be thrown when the device returns an error status or does something strange. There are also some cases where you want to catch an IOExceptionfrom one or more low-level library calls and wrap it in another IOExceptionwith a higher-level message, such as a connectivity check throwing a "Device not available" exception caused by a "Request timed out" exception.

IOException- 接口、网络和硬盘驱动器访问的所有问题都属于此问题。如果您正在编写代码来访问外部数据或硬件,您应该使用它。例如,如果您正在实现一个 API 来访问某种类型的网络设备,您可以创建一个MyDeviceException子类,以便在设备返回错误状态或执行一些奇怪的操作时抛出该子类。在某些情况下,您希望IOException从一个或多个低级库调用中捕获一个,并IOException使用更高级别的消息将其包装在另一个中,例如连接检查会引发由“请求”引起的“设备不可用”异常超时”异常。

IllegalArgumentException- Any parameter checks should throw this. For example, a negative integer for a size parameter, or an unexpected null. This is an unchecked exception, but I recommend documenting it anyway to make the method preconditions more clear. You can find lots of examples in the core libs.

IllegalArgumentException- 任何参数检查都应该抛出这个。例如,大小参数的负整数或意外的null. 这是一个未经检查的异常,但我建议无论如何都要记录它以使方法先决条件更加清晰。您可以在核心库中找到很多示例。

IllegalStateException- You can use this when the method parameters are valid, but some internal data or functionality required by the method is unavailable, and there isn't a more appropriate checked exception (like IOException). It's often better to design things so that this isn't necessary.

IllegalStateException- 当方法参数有效,但方法所需的某些内部数据或功能不可用,并且没有更合适的已检查异常(如IOException)时,您可以使用它。通常最好设计一些东西,使这不是必需的。

UnsupportedOperationException- If you make a subclass of something and one of the superclass methods is conceptually invalid for it, override it and throw one of these. Guava uses this for its immutable collection classes, since Java's collection interfaces aren't designed to support immutability. This tends to be a sign of bad design in the superclass. Don't use it if just doing nothing or returning null/empty would be an appropriate and unsurprising result.

UnsupportedOperationException- 如果您创建某个东西的子类,并且其中一个超类方法在概念上对它无效,请覆盖它并抛出其中一个。Guava 将其用于其不可变集合类,因为 Java 的集合接口并非旨在支持不变性。这往往是超类设计不良的标志。如果什么都不做或返回 null/empty 是一个合适且不足为奇的结果,请不要使用它。

回答by darrengorman

Absolutely it makes sense to reuse Exceptionclasses when they reasonably describe the scenario that caused the exception to be thrown.

Exception当类合理地描述导致抛出异常的场景时,重用类绝对是有意义的。

回答by Louis Wasserman

If users of your code might need to do different things on two different exceptions, then those should be distinct exception types. That said, the JDK exceptions cover most of the "programmer error" exceptions -- if an IllegalArgumentExceptionis getting thrown, for example, that indicates a programming mistake, not something that should be handled at runtime.

如果你的代码的用户可能需要对两个不同的异常做不同的事情,那么这些应该是不同的异常类型。也就是说,JDK 异常涵盖了大多数“程序员错误”异常——IllegalArgumentException例如,如果抛出一个,则表明存在编程错误,而不是应该在运行时处理的问题。