异常处理

 异常体系

 

最佳实战思路

  • 遇到Error(内存溢出、文件损坏、服务器宕机等),程序直接停止运行
  • 为什么要处理异常?为了避免程序运行中止
  • 检查异常(文件找不到、SQLException、IOExcetion、类找不到等)不会自动抛出,必须手动捕获或者手动向上抛出(IDEA会有提示),否则程序无法通过编译
  • 运行时异常(代码逻辑错误,例如数组越界访问、空指针、除数为0等)会自动向上抛出,但如果一直没有得到处理,最终程序也会停止运行(如果是请求,则只是线程终止,并不影响主程序的运行)
  • 一般只抛出自定义运行时异常,结合全局处理器进行处理;但为什么自己很少在代码中抛出自定义异常?因为我通过if条件进行了处理
  • 对于预定义的运行时异常,一般通过预先检查(if 语句)来进行规避

 

检查时异常
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlExceptionDemo {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            // 故意写错数据库URL,触发SQLException
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/wrong_db", "user", "password");
            stmt = conn.createStatement();
            String sql = "SELECT * FROM non_existing_table";
            stmt.executeQuery(sql);
        } catch (SQLException e) {
            System.out.println("捕获到SQL异常!");
            System.out.println("错误信息:" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

 

异常打印的常用函数

// 异常原因
e.getMessage() 

e.getCause().getMessage()

// 打印栈信息
printStackTrace()

 

针对检查异常的两种处理方式

方式一

try-catch-finally捕获

注:

  • 一般来说在之前try或者catch块中的return语句之前会先去执行finally代码块
  • 只有当在 try 或者 catch 中调用退出 JVM 的相关方法,例如 System.exit(0) ,此时 finally 才不会执行,否则 finally 永远会执行。
  • 如果finally 块中有 return 关键字,那么 try 块以及 catch 块中的 return 都将会失效,所以在开发的过程中不推荐在 finally 块中写 return 语句
    public String index(){
        try{
            ......  //可能产生异常的代码 }
            catch( ExceptionName1 e ){
            ......  //当产生ExceptionName1型异常时的处置措施 }
            catch( ExceptionName2 e ){
            ......    //当产生ExceptionName2型异常时的处置措施 }
            finally{
            ......     //无论是否发生异常,都无条件执行的语句 
            }
    }

方式二

抛出异常

注:

  • 至于方法上的throws关键字,则是java强制要求抛出编译时异常时需要声明,抛出运行时异常时不强制声明;
    public String index() throws IOException {
        throw new IOException("test");
    }

 

自定义异常

// 运行时异常会自动向上抛出
public class MyException extends RuntimeException{
    public MyException() {
        super();
    }

    public MyException(String message) {
        super(message);
    }
}

 

全局异常处理

作用:集中统一处理,避免大量重复代码

 

try-with-resources

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryWithResourcesDemo {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // reader 会自动关闭资源
    }
}

 

参考链接

【1】Java 异常处理概念及最佳实战

【2】SpringBoot 全局异常处理

【3】全局异常处理Demo

posted @ 2023-05-08 15:21  先娶国王后取经  阅读(46)  评论(0)    收藏  举报