“抛出异常”的目的

时间:2016-06-14 20:11:50

标签: java exception

SwingWorker方法doInBackground是抽象的,文档说它会抛出Exception,但具体的实现似乎不需要声明它抛出Exception。 Eclipse没有抱怨所以Exception本身似乎不是“已检查”的例外。当然,任何代码都可以抛出一个RuntimeException(这是一个Exception)所以这个文档似乎在说一些多余的东西。

protected abstract T doInBackground()
                             throws Exception

一个具体的例子:

public Boolean doInBackground() // concrete for abstract
{
        performLongRunningProcedure();
        return true;
}

我可以推测,缺少警告可能是IDE和/或语言的限制,但似乎抛出Exception子句可能有实际意义。为什么任何方法,具体或抽象都会声明“抛出异常”?

2 个答案:

答案 0 :(得分:3)

Beri提供的链接解释了声明跨方法抛出异常的技术规则。回答你的问题"为什么抛出异常":

在一个具体的(可能放在"最终"在这里,但我赢了)方法一个人几乎不需要声明"抛出异常",因为一个具体的方法将确切知道它可能抛出的异常,并应明确列出。

抽象方法/接口方法不同。你有三个选择:

  1. 不要声明任何抛出的异常。这意味着任何实现可能抛出的唯一异常是RuntimeException。这意味着不会抛出任何已检查的异常,并且在几乎所有情况下都应该安全地调用此方法而不会出现故障。如果它确实抛出异常,那么你无能为力。
  2. 抛出特定的已检查异常。这可以做到,但是在极少数情况下,抽象方法可以正确地预测可能抛出的确切有限的已检查异常集。在使用插件编写框架时,这将是一种指定框架理解如何处理的已检查异常的方法(例如,流类中的IOException,FileNotFound)。这样做的含义是,定义的集合是唯一可能发生或有意义发生的已检查异常。
  3. 抛出异常。在这种情况下,它表示允许具体实现抛出任何对该实现有意义的已检查异常,没有任何限制。实现可能会选择抛出更少(或没有),但允许抛出任何已检查的异常。它表示允许实现抛出任何已检查的异常,并且将需要调用者处理异常。
  4. 它没有增加太多价值。为什么不?因为已检查异常的值是理解可以抛出的特定异常,以便调用者可以有意义地处理它们。当你只剩下" Exception",并没有指出实现可能会抛出什么(或者,有多个实现,可能会有所不同),没有有意义的方法来处理这不仅仅是处理Exception,它实际上没有比处理RuntimeException更有意义。

    因此,使用"声明抽象方法的唯一真正价值是抛出异常"是明确地说"我们要求调用者显式处理这种方法可能抛出的异常,因为我们不能保证实现是否可能抛出它们。"因此,不要希望实现不会抛出异常,而是必须假设它发生异常。

答案 1 :(得分:1)

  

SwingWorker方法doInBackground是抽象的,文档说它会抛出Exception,但具体实现似乎不需要声明它抛出Exception。< / p>

抽象方法声明有时它允许覆盖方法声明这样的throws Exception,如果它们做了一些可以在不处理异常的情况下抛出异常的操作。

我知道有些人不理解,所以这里有一些代码无法编译:

abstract class Foo {
    abstract void foo();
}

class Bar extends Foo {
    @Override
    void foo() throws InterruptedException { Thread.sleep(5000); }
}

Eclipse将拒绝此代码,并声明Exception InterruptedException is not compatible with throws clause in Foo.foo()javac也是如此,但我不知道它是否提供相同的错误消息。)

  

Eclipse没有抱怨所以Exception本身似乎不是&#34;检查&#34;异常。

     

似乎抛出Exception子句

可能有实际意义

The way checked exceptions work is throroughly explained in the official Java tutorial.