Java:声明抛出异常和声明抛出哪些异常之间是否存在语义差异?

时间:2016-04-18 08:17:34

标签: java exception

由于此问题的最终编辑已被标记为重复:此问题是关于throws声明的语义 - 这个问题就是这个问题成为处理throws不同方面的副本,而这15个答案中没有一个给了我所选答案的见解。无论如何 - 让我们把它作为副本保存在这里。

在Java中,您必须声明一个throws子句并命名此方法可能引发的异常 - 所以简单的方法就是声明

void myMethod(...) throws Exception

或者您可以更具体,例如州

void myMethod(...) throws SQLException, NamingException

如果该方法可能只抛出这两个。

我知道是否在try / catch块中

会有所不同

try { ... } catch (Exception exc) { ... }

try { ... } catch (SQLException | NamingException exc) { ... }

因为第一个也会捕获RuntimeException,第二个也不会 - 所以这是一个区别。

但声明throws Exceptionthrows SQLException, NamingException关于程序语义的问题是否也有区别?第二个可能更具可读性,但我没有看到任何其他差异。有没有?

4 个答案:

答案 0 :(得分:2)

  

但声明throws SQLException, NamingExceptionthrows SQLException, NamingException

之间是否存在任何差异

区别在于:

  • 如果您声明Unhandled exception type ...,编译器会确保您已准确捕获这两个例外。否则,您将收到throws Exception错误。

  • 另一方面,如果您声明Exception,编译器会确保您已捕获Exception

在第二种情况下,您仍然可以捕获从Exception继承的任何其他异常,而不会出现编译器错误(例如“Exception ... never thrown”)。但是,您必须捕获throws Exception本身private void someMethod() throws Exception { throw new NumberFormatException("Illegal number format"); } 添加到调用方法以允许进一步向上传递异常。例如,

NumberFormatException

如果调用此方法,您可以捕获Exception,但您还必须处理更通用的public void myMethod() { try { someMethod(); }catch(NumberFormatException nfe) { nfe.printStackTrace(); }catch(Exception ex) { ex.printStackTrace(); } } 在throws子句中声明它(和然后在调用层次结构中进一步处理它:

public void myMethod() throws Exception {
    try {
        someMethod();
    }catch(NumberFormatException nfe) {
        nfe.printStackTrace();
    }
}

或者:

Dockerfile

答案 1 :(得分:1)

是的,有区别。

当您在方法中使用 throws 声明时,您可以在以后处理它(使用try {} catch块)。

当您处理异常时,您可能只是执行e.printStackTrace(),但这并没有真正处理它。

相反,想象一下你想告诉你的用户"你没有介绍一个号码,请纠正这个错误"并提示他们介绍一个号码。如果在用于读取的方法中抛出 NumberFormatException ,则可以执行此操作。但是如果只抛出异常,你就无法确定这是错误还是其他任何异常,并且你可能会因此而出现意想不到的行为。

答案 2 :(得分:0)

两种方法之间的区别在于异常处理。例如,如果您希望以相同的方式处理所有异常,那么您应该选择第一种方法。另一方面,如果你想以不同的方式处理不同的例外,你必须采取第二种方法

答案 3 :(得分:0)

我更愿意在throws关键字后的函数声明中明确提到异常,因为我知道如果它们出现在调用代码中我应该如何处理这些异常。请参阅下面的代码以便更好地理解..

public static void exceptionExample() throws SQlException, NamingException {

    }   

public static void main(String[] args) throws SQlException, NamingException {

    try {
        exceptionExample();
        exceptionExample();
    }
    catch(SQlException e){  
        System.out.println("Sql exception has occured");
    }
    catch(NamingException e){
        System.out.println("Naming Exception has occured");
    }   

  } 
  • 如果我没有在函数中明确提到throws SQlException , NamingException并且只使用throws Exception那么它意味着我不知道可能发生哪个异常。在catch() {...}块的情况下,我会使用e.printStackTrace这不是一种有效的异常处理方法,因为用户可能永远不会知道应用程序发生了什么。但是在这里您可以看到我可以通知用户发生了相应的异常,这使我的应用程序更加用户友好。

  • 此外,投掷Exception会导致调用代码捕获他们可能不想处理的异常,具体取决于应用程序和各种原因。

  

所以我想说这取决于程序员的机智,他/她想如何有效地处理异常......