为什么尝试/抓住扔掉?

时间:2011-05-12 22:17:58

标签: java checked-exceptions

在尝试重构某些代码时,我试图在catch子句中抛出异常,就像这样 -

try {
....
}
catch(Exception exception){
.....
throw exception
}

然而,当我试图在线上抛出异常“抛出异常”时,编译器抱怨我需要在新的try / catch中包含我的throw子句,如下所示 -

try
{
  ....
}
catch (Exception exception)
{
  .....
  try
  {
    throw exception
  }
  catch (Exception e2)
  {
     ...
  }
}

为什么编译器需要这个以及它提供了什么用途?

由于

4 个答案:

答案 0 :(得分:3)

异常java.lang.Exception是一个已检查的异常。这意味着它必须在封闭方法的throws子句中声明,或者使用方法体捕获和处理。

但是,你在“修复”版本中所做的是捕获异常,重新抛出它然后立即再次捕获它。这没有多大意义。

没有看到真正的代码,不清楚真正的解决方案应该是什么,但我希望问题出现在原来的try { ... } catch处理程序中:

  • 如果可能,您应该在此时捕获更具体的异常,这样当您重新抛出它时,它将被方法的现有throws列表覆盖。

  • 或者,您可以将异常包装在未经检查的异常中,然后将其抛出。

  • 作为最后的手段,您可以更改方法的签名以在投注列表中包含Exception。但这是一个非常糟糕的主意,因为它只会将问题推迟给调用者......并使开发人员/读者处于不知道期望什么异常的位置。

答案 1 :(得分:1)

在原始代码中,没有任何内容捕获抛出的异常。我想你要么必须指定你的函数抛出异常,要么有另一个try / catch块,因为编译器建议捕获它。

而不是

public void yourFunction(){
  try {
    ....
  }
  catch(Exception exception){
    .....
    throw exception
  }
}

public void yourFunction() throws Exception{
  try {
    ....
  }
  catch(Exception exception){
    .....
    throw exception
  } 
}

答案 2 :(得分:1)

在Java中,已检查和未检查的异常之间存在区别。未经检查的异常基本上可以在代码中的任何位置抛出,如果它没有被捕获到某处,它将传播到应用程序的入口点,然后停止进程(通常带有错误消息和堆栈跟踪)。检查的异常是不同的:编译器不允许你让它传播,你需要包围任何可能使用try-catch块抛出一个已检查异常的代码(如果异常是一个“抛出异常”是最简单的情况)已检查的异常类的实例)或者您必须将包含对代码的调用的方法标记为可能使用“throws”声明抛出已检查的异常。如果所需的行为是抛出未经检查的异常,那么您需要在RuntimeException中包装异常。如果所需的行为是检查异常,那么您需要向当前方法添加throws声明。

答案 3 :(得分:0)

我的猜测是你试图抛出一个未被方法声明的异常子类作为它可以抛出的异常类型。

以下示例有效

package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws Exception{
        try {
            int value = 1/0;
        } catch (Exception e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}

但是这个例子会出错。

package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws RuntimeException{
        try {
            int value = 1/0;
        } catch (Exception e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}

注意在第二个例子中,我只是捕获E​​xception而不是RuntimeException,它不会编译,因为我抛出Exception,这是一个未声明的throws,即使我确实声明了RuntimeException。

是的,异常是RuntimeException,但编译器不知道。

想到第三个工作示例向您展示。这个也有效,因为你投掷的声音与你声明的相同。 (注意唯一的变化是捕获块)

package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws RuntimeException{
        try {
            int value = 1/0;
        } catch (RuntimeException e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}

您需要了解所有这三个答案之间的差异