2011-05-12 69 views
0

在试图重构一些我的代码我试图抛出异常的catch子句中像这样 -为什么尝试/赶上可抛弃?

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

然而,当我试图扔上线“抛出异常”异常的编译器的消息抱怨我需要我的周围扔子句中一个新的try/catch像这样 -

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

为什么编译器需要这一点,它提供了有什么用?

谢谢

+0

感谢所有的答案,代码是一个线程,所以我不的run方法中认为我可以抛出异常? – 2011-05-12 22:41:31

+0

[Throw error to calling method!]可能的重复(http://stackoverflow.com/questions/5976764/throw-error-to-calling-method) – McDowell 2011-05-12 22:50:35

+0

我不这么认为,但也许我错了,我真的想知道的是为什么我需要围绕“抛出异常”与try catch。抛出异常时,抛出异常不能抛出异常吗?尝试 { 抛出异常 } 赶上(例外E2) { ... } – 2011-05-12 22:57:35

回答

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; 
     } 

    } 

} 

然而这个例子会给出一个错误。在第二个例子中,我简单地捕捉异常不是RuntimeException的

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; 
     } 

    } 

} 

注意,它不会编译,因为我抛出的异常是一个未声明的抛出,即使我做申报的RuntimeException。

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

只是想到了第三个工作实例来向你展示。这一个也适用,因为你抛出相同的类型,你声明。 (注意,唯一的变化是catch块)

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; 
     } 

    } 

} 

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

1

在您的原始代码中,没有任何东西能够捕获抛出的异常。我想你要么指定你的函数抛出一个异常,要么有另一个try/catch块,因为编译器建议去捕捉它。

而不是

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

尝试

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

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

但是,你在做什么在你的“固定”版本来捕获异常,重新抛出它,然后立即再次抓住它。这没有什么意义。

没有看到真正的代码,目前尚不清楚真正的解决方案应该是什么,但我相信这个问题是在原try { ... } catch处理程序:

  • 如果可能的话,你应该捕获更具体在那个时候例外,所以当你重新抛出时,它被方法现有的throws列表覆盖。

  • 或者,你可以包装在unchecked异常异常,并抛出来代替。

  • 作为最后的手段,你可以改变方法的签名,包括Exception在抛出名单。但这是一个非常糟糕的主意,因为它将问题推给了调用者......并使开发人员/读者处于不知道预期会出现什么异常的位置。

+0

我已经看到了用于捕捉和重新抛出有效的情况下。那些说...可能会记录的行。他们可能是异常本身的逻辑等 – Wes 2011-05-12 22:24:55

+0

@Wes - 我正在谈论的“固定”版本的代码。我声称嵌套的'try catch'没有任何意义。你可以删除try块并内联catch块,它会以较少的代码行速度更快地完成同样的事情。 – 2011-05-12 22:36:40

+0

无论如何,我还是喜欢你的答案。对于你所声称的,我只是有点困惑。请注意,这是在我看到您的编辑之前。 – Wes 2011-05-12 22:37:56

1

在Java中,在checked和unchecked异常之间存在区别。一个未经检查的异常基本上可以在代码的任何地方被抛出,如果它不是某个地方捕获,它会传播到你的应用程序的入口点,然后停止进程(通常是用一个错误信息和堆栈跟踪)。经过检查的异常是不同的:编译器不会让你就让它传播,你需要或者围绕这可能会引发使用try-catch块(与“抛出异常” checked异常的任何代码是最简单的情况下,如果异常是一个检查的异常类的实例),或者您必须标记包含可能通过“抛出”声明抛出检查异常的代码调用的方法。如果期望的行为是抛出未经检查的异常,那么您需要将该异常封装在RuntimeException中。如果希望的行为是保持异常检查,那么你需要添加一个throws声明到你当前的方法。