【问题标题】:Declaring the same checked exception multiple times多次声明同一个检查异常
【发布时间】:2015-02-03 20:28:15
【问题描述】:

我刚刚意识到我可以编写一个方法多次声明同一个检查异常。

public void myMethod() throws MyException, MyException, MyException {

我想不出为什么要这样做。我一直在寻找一段时间,但我无法找到是否有资源可以解释为什么这是可以接受的,或者它怎么可能是好的。谁能给我指点这方面的资源?

【问题讨论】:

  • 你认为throws是什么意思?
  • 语法有时允许很多不合逻辑的东西,问题是你为什么要写这样的东西?
  • 我认为这完全与语法有关,就像您编写 throws MyException 一样。限制这一点,将是编译器的多余检查。
  • 我想不出为什么我会声明一个变量 int useless = 0; 并且从不使用它的原因,但 Java 允许我这样做。也许你想这样写来增加可读性。
  • 这是一个类型定义。如果您多次声明它,编译器为什么会关心它? java 术语中有多少其他地方多次声明特定类型是一个问题?我希望只有在涉及变量名时才会出现问题

标签: java exception checked-exceptions


【解决方案1】:

JLS 中没有任何内容可以阻止您在 throws 子句中指定相同的异常类型(甚至是子类型)。根据JLS, Section 8.4.6,唯一的限制是:

如果 throws 子句中提到的 ExceptionType 不是 Throwable 的子类型(第 4.10 节),则会出现编译时错误。

所以,这编译:

throws RedundantException, RedundantException, RedundantException

我的 IDE 警告我“重复抛出”,但这不是编译器错误。

我认为没有充分的理由这样做。我从来没有想过要尝试这个。

即使MySubclassExceptionMyException 的子类,也会编译:

throws MyException, MySubclassException, MyException, MySubclassException

我能想到在throws 子句中列出子类异常类型的唯一原因是在您自己的Javadocs 中记录可能会抛出子类,因此可以单独处理。

@throws MyException If something general went wrong.
@throws MySubclassException If something specific went wrong.

即便如此,我的 IDE 还是会警告我列表中有“更普遍的例外”。

顺便说一句,是否检查上述示例中的任何异常类型似乎并不重要。

【讨论】:

  • 一个实际的例子:java.nio 中的一些方法抛出 IOException 以及一个“可选的特定异常”,如 FileAlreadyExistsException(IOException 的子类型)。
【解决方案2】:

rgettman's answer 中所述,重复的throws 声明没有语义意义。但是,javac 仍然将它们记录在编译后的类文件中,使它们可用于反射,如下例所示:

public class Main {
    public static void main(String[] args) throws IOException, IOException,
            IOException, NoSuchMethodException {
        Arrays.stream(Main.class.getMethod("main", String[].class).getExceptionTypes())
                .forEachOrdered(System.out::println);
    }
}

打印出来的

class java.io.IOException
class java.io.IOException
class java.io.IOException
class java.lang.NoSuchMethodException

这没有用(并且可能暴露了Method.getExceptionTypes() 的错误消费者),但这是由重复的throws 声明引起的行为差异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2014-10-09
    • 2012-01-11
    • 1970-01-01
    相关资源
    最近更新 更多