当前位置: 首页 > 知识库问答 >
问题:

为什么编译器在方法永远不会抛出异常的情况下允许抛出

辛承志
2023-03-14

我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。

因为有两种处理异常的方法(抛出和try/catch)。在try/catch中,它不允许捕获try块中未抛出的异常,但它允许在不抛出异常的方法中抛出。

private static void methodA() {
    try {
        // Do something
        // No IO operation here
    } catch (IOException ex) {  //This line does not compile because
                              //exception is never thrown from try
        // Handle   
    }
}

private static void methodB() throws IOException { //Why does this //compile when excetion is never thrown in function body
    //Do Something 
    //No IO operation
}

共有1个答案

百里海超
2023-03-14

throws子句是方法契约的一部分。它要求方法的调用方的行为就好像指定的异常可能由方法引发一样(即,或者捕获异常,或者声明它们自己的throws子句)。

方法的初始版本可能不抛出throws子句中指定的异常,但未来版本可以抛出它而不破坏API(即调用该方法的任何现有代码仍将传递编译)。

相反也有可能。如果用于抛出throws子句中指定的异常的方法,但它的未来版本不再抛出它,则应保留throws子句,以免破坏使用您的方法的现有代码。

第一个例子:

假设您有使用methodB的代码:

private static void methodA() {
    methodB(); // doesn't have throws IOException clause yet
}

如果稍后要更改MethodB以抛出IOExceptionMethodA将停止传递编译。

private static void methodA() {
    try {
        methodB(); // throws IOException
    }
    catch (IOException ex) {

    }
}

如果从methodB的未来版本中删除throws子句,methodA将不再传递编译。

methodaprivate时,这个示例就不太有趣了,因为它只能在本地使用(在同一个类中,很容易修改调用它的所有方法)。

但是,如果它变成public,您就不知道谁使用(或将要使用)您的方法,因此您无法控制由于添加或删除throws子句而可能中断的所有代码。

如果是实例方法,那么即使不抛出异常也允许throws子句还有另一个原因--方法可以被重写,重写方法也可能抛出异常,即使基类实现不这样做。

 类似资料:
  • 问题内容: 在下面的源代码中,我抛出一个。 为什么没有必要将关键字放在方法的签名上? 问题答案: 仅在Java 1.7上会出现此现象。使用1.6进行编译时,出现以下编译器错误消息: 但是,使用Java 1.7可以编译。 …直到我实际把一个块扔了进去: 编译中… 看起来Java 1.7足够聪明,可以通过分析块代码来检测可能抛出的类型,而1.6刚看到类型并为此给出了错误。 对其进行更改以使其按预期方式

  • 问题内容: 如果有一些代码显然不能引发异常,则Java编译器似乎不一致,而您编写的周围代码声明该代码可以引发该异常。 考虑这些代码片段。 片段1 一个是永远不会抛出异常。 是带信息的编译错误 片段2 表示从未抛出的异常的声明。 它编译良好。 因此,第一个代码段的结果表明,编译器可以计算方法是否可以引发列表中列出的异常。因此,似乎编译器 故意 不报告第二个片段的错误。但为什么?为什么即使编译器知道无

  • 问题内容: 我有这样的方法: 我想抛出一个内。编译器不允许我这样做,因为不允许将我的方法扔在那里。但是我需要抛出一个的子类来进行测试 (我不能抛出Unchecked)。显然这是一个hack,但我需要进行测试。我尝试过EasyMock,但它也不允许我这样做。任何想法如何做到这一点? 谢谢,肖恩·阮 问题答案: 方法1: Alexey Ragozin的这篇文章介绍了如何使用泛型技巧引发未声明的检查异常

  • 下面是我的代码。当我运行它时,我在线程“main”java.lang.IndexOutOfBoundsException:Index:3、Size:2中得到异常,而不是我的异常消息。谁能解释一下我做错了什么,为什么会这样?谢谢!

  • 问题内容: 我偶然发现该语句(从一些更复杂的代码中摘录)进行编译: 在短暂但快乐的时刻,我认为受检查的异常最终决定已经死亡,但是对此仍然感到遗憾: 该块不必为空;似乎可以有代码,只要该代码不引发检查异常即可。这似乎是合理的,但是我的问题是,语言规范中的哪个规则描述了此行为?据我所知,§14.18throw语句明确禁止使用它,因为表达式的类型是已检查的异常,并且不会被捕获或声明为被抛出。(?) 问题

  • 编译器知道检查的异常不能在安全方法内抛出-所以也许它应该允许只捕获未检查的异常? 回到主要问题--有没有理由以这种方式实现捕获检查异常?这仅仅是设计中的一个缺陷还是我遗漏了一些重要的因素--也许是向后的不兼容性?在此场景中,如果只允许捕获,可能会出现什么问题?实例非常感谢。