Java 中捕获与抛出异常

Catching versus Throwing Exceptions in Java

所以我有两个关于 java 的一般性问题。第一个是什么时候在方法主体中使用 try/catch 与在声明方法时使用 throws 异常?这是我的意思的一个小例子。这个:

public void whileChatting() throws IOException{}

对比

public void closeConnection() {
    try {
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
}

然后我的第二个问题是什么时候知道捕获或抛出哪种类型的异常?我指的是 IOException 或 EOFException 等异常...

如果有好人 link 可以派我来教这一切(因为它可能比我想象的更复杂),我会像你回答它一样感激。 谢谢

你要治疗它的原因就用try/catch,否则你应该传播它以便在适当的时候治疗它。

一个好的开始是 javadoc and tutorialspoint for exceptions

两个好的经验法则:

没有硬性答案。

一般来说,您使用 "throws" 的频率可能比使用自定义 "try/catch" 的频率高得多。仅仅是因为 "decision" 模块 "know how to recover" 相对较少,但是相应地 "many" 模块 可能 抛出异常。

抛出异常

在你的第一个例子中,

public void whileChatting() throws IOException{}

意味着它只会向调用该函数的任何对象抛出异常。然后可以在使用 try-catch 块调用该方法时捕获它。比如

try{
    whileChatting();
}
catch(IOException e){
    e.printStackTrace();
}

抛出一个方法基本上是将它向上传播到链中,因此任何调用此方法的方法也需要包含 throws IOException,否则异常将需要在更高级别的方法中处理(通过通常是 try-catch 块的手段)。

捕获异常

捕获异常是一种优雅地处理异常的方式。常见的做法是 e.printStackTrace(); 将错误的详细信息打印到控制台,但这并不总是必要的。有时您可能想要 System.exit(0) 甚至 System.out.println("Error in method whileCalling()")

使用 catch 块,您可以捕获任何类型的异常!你也可以做一个 try-catch-finally 块,它将 运行 try 块中的代码,捕获任何异常,无论是否捕获到任何异常,它都会进入 finally 块并且 运行代码。

要了解您可能需要捕获的异常,您可以查看可能引发异常的 class 的 Javadocs。在那里你会找到 class 可以抛出的所有可能的东西的列表。您也可以只捕获 Exception ,它将捕获任何可以想象的异常! (好吧,授予它扩展异常)

最后你可以 link 像这样一起抓块。

try{
    whileCalling();
}
catch(IOException e){
    //handle this situation
}
catch(FileNotFoundException e){
    //handle this situation
}
catch(Exception e){
    //handle this situation
}

这将像 else-if 块一样工作并且不会捕获重复项。

所以基本上回答你的问题:

1:throw 异常意味着让其他人处理它,无论这是另一个 class、另一个方法,还是只是为了希望它不会发生,否则你的程序会崩溃(非常糟糕的做法)。

2: 使用 try catch 块实际上是按照您认为合适的方式处理异常!打印出堆栈跟踪以进行调试或给用户一个新的提示以重新输入一些东西。 (例如提示用户需要输入文件位置然后抛出 FileNotFoundException

希望对您有所帮助!

基本上是这样的:

  1. throws - 抛出异常的函数告诉它的父函数它出错了。例如,您有一个 createFunction() throws SQLException,您试图在数据库中插入 100 个项目,但创建编号 98 失败。 createFunction() 用于接收此 SQLException 的 main()

  2. try/catch - main() 知道 createFunction() 假设在出现问题时抛出 SQLException,因此当它实现时将它放在 try/catch 块 中,这样如果实际上抛出了 SQLException可以在 catch 块中执行回退计划,例如数据库回滚。

    我刚才说的实际代码:

     createFunction(Connection connection) throws SQLException {
          //insert items in the database
     }
    
     main(){
    
        try{
         createFunction(connection);
        }
        catch (SQLException e){
          connection.rollback();
        }
     }