我该如何知道一个方法可能会抛出哪些异常?

3

我如何知道从方法调用中可能抛出哪些异常?

6个回答

6
查看方法签名中的throws子句以查看可能抛出的“已检查”异常。方法的调用者将不得不在自己的throws子句中传播此信息,或处理异常。
没有100%可靠的方法可以知道会抛出什么RuntimeExceptionError类型。这些类型的想法是它们不太可能被恢复。通常,高级别异常处理程序充当“捕获所有”以记录、显示或报告RuntimeException。根据应用程序的类型,它可能在那一点上退出或继续运行。
一些API确实使用JavaDoc标记记录可能引发的运行时异常,就像检查的异常一样。但是编译器不强制执行此操作。
一般来说,不会捕获Error。这些指示运行时存在严重问题,例如内存不足。

2

您看到了“throws”子句。

无法确定会抛出哪些未经检查异常。

如果您的程序想要知道这一点,请使用反射来反射“throws”列表。


2
请看方法声明(或Javadoc),它将列出可以从该方法中抛出的所有“已检查异常”。 任何方法都可以抛出任何“未检查异常”。 已检查异常是从java.lang.Exception派生的任何异常(包括Exception本身),但不包括java.lang.RuntimeException及其子类。未检查异常是从Throwable派生的类型(包括Throwable),除了不派生自Exception的RuntimeException及其子类。不,这并不是特别好的设计思路...

在Javadoc中,左侧写着“Exceptions”。那是指未经检查的异常还是经过检查的异常?在类内容页面中,在“Throws”之后列出的是未经检查的异常还是经过检查的异常? - ajsie
无论是已检查的异常还是未检查的异常,您都可以声明一个方法会抛出异常。我不确定您所说的“在左边”是什么意思。 - Jon Skeet
如果你点击一个包,然后在它下面你可以找到内容。类,异常和错误。它们指的是什么类型的异常,已检查还是未检查?如果是已检查的,哪里可以找到运行时异常?http://java.sun.com/j2se/1.5.0/docs/api/ - ajsie
根据我上面所说的规则,它们会被标记为已检查或未检查 - 如果它们派生自“RuntimeException”或不派生自“Exception”,则它们是未检查的 - 否则它们是已检查的。 - Jon Skeet

2

已检查异常——那些不是从RuntimeException扩展的异常——在方法签名上声明,必须被捕获或在使用这些方法的其他方法的签名上声明。编译器进行这些检查,如果违反了这些原则,将无法完成构建。

未检查异常——RuntimeException及其子类——不需要声明,并且可以由任何方法抛出。

话虽如此,如果您的方法通常会引发未检查的异常,最好在Javadoc中记录该事实。

如果您需要捕获可能在您的方法中抛出的任何异常,可以始终捕获Exception或Throwable。这种方法在通用库或API的边界处很常见,允许它们将传出异常包装在标准类型中并包括特定于API的错误信息。


在“RuntimeException和子类”中,子类是什么意思? - ajsie
我在哪里可以找到所有未检查的异常列表? - ajsie
@Ajsie: "and subclasses" 表示 "RuntimeException 的子类和其它相关的类"。 - Lawrence Dol

1
对于检查异常,方法调用中的 "throws" 将告诉您整个故事。
未检查的异常则稍微复杂。基本上,您需要绘制一个由该方法调用的所有方法的树,并列出它们中任何一个可能调用的所有未检查异常。
当然,这将包括在这些类中抛出但未捕获的任何内容,当然还包括来自 Java 标准库以及项目中的任何其他库的方法。
因此:如果您真的非常想知道,那么可以,但可能需要一些工作。

@Carl - 未经检查的异常比那更复杂。考虑NullPointerException和OutOfMemoryError。 - Stephen C
没错。手动检查 NPE 非常困难,OOM 更是不可能。这就是为什么我们需要全面的测试吧。 - Carl Smotricz

1

对于受检异常,请简单查看方法签名。如果方法声明了throws异常,那么该方法(或子类中的方法覆盖)可能会抛出该异常或其子类。

对于未受检异常,在理论上任何未受检异常都可能被任何方法调用抛出。(您可以为方法签名添加未受检异常的throws,但就编译器而言,这是多余的。这个throws仅作为文档说明。)

获取更明确的答案的唯一方法是使用某些(假设存在的)源代码或字节码分析器。例如,您可以通过检查完整代码库中没有new SomeException(...)的实例来确定某些异常从不被抛出或传播。但对于某些异常(例如NullPointerException和OutOfMemoryException),除非在非常有限的情况下,否则此分析将是棘手的。


左侧Javadoc中的异常是指运行时异常吗? - ajsie
不确定你在说哪个,但 Javadoc 只记录检查异常,抱歉。 - Carl Smotricz
@Ajsie - javadoc 中方法的异常是指方法签名声明要 throws 的异常。 - Stephen C
@Carl - 你确定吗?我相当确定我可以在Sun Java文档中找到未经检查的异常示例。 - Stephen C
我的意思是在Javadoc的左下角框架中。在错误上面,我们得到了异常。这些是未经检查还是已经检查(运行时)异常? - ajsie
你的意思是像这样的网址 http://java.sun.com/javase/6/docs/api/java/lang/package-frame.html 吗?在“Exceptions”标题下列出的类是已检查和未检查的异常类。请注意,有一个单独的“Errors”标题用于错误类。在传统的Java术语中(例如JLS),小写的“exception”一词指的是Exception和Error类/子类的实例。 - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接