当前位置: 首页 > 面试题库 >

为什么Java编译器允许在throws部分中列出无法抛出方法的异常

司寇研
2023-03-14
问题内容

如果有一些代码显然不能引发异常,则Java编译器似乎不一致,而您编写的周围代码声明该代码可以引发该异常。

考虑这些代码片段。

片段1

一个catch是永远不会抛出异常。

public void g(){
        try {

        } catch (FileNotFoundException e) {//any checked exception

        }

}

是带信息的编译错误

Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body

片段2

throws表示从未抛出的异常的声明。

public void g() throws FileNotFoundException{
}

它编译良好。

因此,第一个代码段的结果表明,编译器可以计算方法是否可以引发throws列表中列出的异常。因此,似乎编译器 故意
不报告第二个片段的错误。但为什么?为什么throws即使编译器知道无法抛出这些异常,编译器为何仍允许您在本节中编写异常?


问题答案:

编译器允许这样做,因为throws方法的子句是方法 签名 的一部分,而不是其 实现的
一部分。在使签名保持相同的同时,实现可能会在某个时候进行更改。旧的实现可能引发了检查异常,而新的实现则没有。否则,签名的设计者可能希望为实现者提供灵活性,使其在并非总是必要时抛出已检查的异常。



 类似资料:
  • 我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。 因为有两种处理异常的方法(抛出和try/catch)。在try/catch中,它不允许捕获try块中未抛出的异常,但它允许在不抛出异常的方法中抛出。

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

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

  • null 为简洁起见,排除了getter和setter(用于所有字段)以及toString()。 我尽了最大的努力按照指导原则格式化代码,但它没有发生,请耐心等待。 @Entity@Table(name=“Products”)@XmlRootElement@NamedQueries({@NamedQuery(name=“Product.FindAll”,query=“从产品p中选择p”),@nam

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

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