由于此问题的最终编辑已被标记为重复:此问题是关于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 Exception
与throws SQLException, NamingException
关于程序语义的问题是否也有区别?第二个可能更具可读性,但我没有看到任何其他差异。有没有?
答案 0 :(得分:2)
但声明
之间是否存在任何差异throws SQLException, NamingException
与throws 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
会导致调用代码捕获他们可能不想处理的异常,具体取决于应用程序和各种原因。
所以我想说这取决于程序员的机智,他/她想如何有效地处理异常......