异常类型及 try 注意点

本文介绍了Java中的异常处理机制,包括受查异常(编译异常)和非受查异常(运行异常)。受查异常如IOException必须处理,可通过try-catch或向上抛出。非受查异常如NullPointerException可不处理,但可能导致程序终止。try-catch-finally语句用于捕获和处理异常,finally块确保资源释放。异常向上抛至主函数由JVM处理,也可手动throw异常。自定义异常可继承Exception或RuntimeException来创建编译时或运行时异常。

异常:所谓异常指的是程序在运行时出现错误时通知调用者的一种机制。

异常分为两大类:受查异常(编译异常)非受查异常(运行异常)

一、受查异常(编译异常):

受查异常主要为:Exception(异常类父类)。

常见的受查异常是:找不到类异常、IO 异常等多种。

受查异常必须解决,且需要显示处理

受查异常处理方式包括:可以向上抛和直接通过try包裹

二、非受查异常(运行异常):

非受查异常主要为:Error(错误类)、RuntimeException 

常见的非受查异常是:空指针异常、数组下标越界异常、算数异常等。

非受查异常可以不直接处理,可以 try 或者向上抛

运行异常不解决的话,会导致程序终止,程序终止会自动调用 printStackTrace()  函数


try(有可能出现异常的代码块):

1、try 中捕捉到异常会立刻结束 { } 中的代码,进入对应的 catch

2、try 也可以回收资源:

try (Scanner sc1 = new Scanner(System.in)) {
       int num = sc1.nextInt();
       System.out.println("num = " + num);
} catch (Exception e) {
       e.printStackTrace();
}

catch(异常对象的处理):

1、可以 catch 捕获 Exception类(所有异常的父类),但是非常不推荐。

2、catch 只能处理对应种类的异常。

3、catch 进行类型匹配的时候,不光会匹配相同类型的异常对象,也会捕捉目标异常类的子类对象

4、try 中发生异常后会在 catch 中捕捉对应的异常,如果自己没有捕捉则交给JVM处理(但也会执行finally)。

5、catch 中的异常类型可以用 | 隔开。

try{
   System.out.printly("这是可能出现异常的代码块")
}catch(Kind1Exception | Kind2Exception | Kind3Exception){
   System.out.printly("处理规则")
}finally{
   System.out.printly("善后处理")
}

6、printStackTrace() 函数:栈跟踪,查看异常代码调用栈,即打印异常信息(位置和类型)的方法。打印出的信息在控制台不确定。常在catch中调用。


finally(处理善后,可以不加):

1、finally 可以节约资源

2、finally 不论是否抛出异常、是否catch到异常都会执行,但前面必须由try语句,否则出错。

3、finally 中不要写 return这会被编译器当作一个警告。因为 finally 执行的时机是方法返回之前(try 或 catch 中的 return 之前),但如果 finally 也有 return,只会执行 finally 中的 return ,不会执行 try 中的 return。


异常向上抛:

向上抛需要抛具体的异常类,最多抛至主函数,此时由JVM处理。

当JVM处理异常时,程序会立即异常终止。


手动抛出异常:

throw new 编译时异常或运行时异常,一般为运行时异常。

class Text{
    public static int divide(int x, int y) throws ArithmeticException{
           if (y == 0) {
                throw new ArithmeticException("抛出除 0 异常");
           }
           return x / y;
    }
    public static void main2(String[] args) {
        //手动抛出异常
        System.out.println(divide(10, 0));
    }
}

自定义异常:

继承自 Exception 默认为编译时异常(受查异常)

继承自 RuntimeException 默认为运行时异常(非受查异常)。

//自己创建用户登录
class NameException extends RuntimeException{     //用户名异常类
//RuntimeException是运行时异常,即非受查异常 
//受查异常不可以通过编译,必须立刻处理
      public NameException (String name){
                System.out.println("八嘎!用户名错误!");
      }
}

class PasswordException extends RuntimeException{      //密码异常类
      public  PasswordException  (String password){
                System.out.println("八嘎!密码错误!");
      }
}

class Text{
      private static final String name = "zhouzhou";       //真正用户名
      private static final String password = "gugaguga24678";    //真正密码
 
      public static void login(String name, String password){  //静态方法调用异常类
           if (!GaGa7.name.equals(name)){
                throw new NameException(name);
           }
           if (!GaGa7.name.equals(password)) {
                throw new PasswordException(password);
           }
      }

      public static void main(String[] args) {     //主方法执行
      //手动自定义登录的异常
           try{
                 login("zhouzhou","gugaguga真呀真多呀");
           }catch(NameException e){
                 e.printStackTrace();
           }catch(PasswordException e){
                 e.printStackTrace();
           }finally{
                 System.out.println("finally已执行。");
           }
       }
}

受查异常(编译异常)和非受查异常(运行异常)最好 try ,越早解决越好。


(文章参考:周周 嘿嘿:异常类型学习

<think>我们正在讨论Javatry-catch语句可以捕获的异常类型。根据用户的问题,我们需要解释Javatry-catch块可以捕获哪些类型的异常,并参考提供的引用内容。 根据引用[2][3],try-catch结构用于捕获处理异常。在catch子句中,我们可以指定要捕获的异常类型Java中的异常类型主要分为两大类:`Exception`(异常`Error`(错误),而`Exception`又分为检查型异常(checked exceptions)检查型异常(unchecked exceptions,也称为运行时异常)。 1. **检查型异常(Checked Exceptions)**: - 这些异常在编译时被检查,必须被捕获或声明抛出(使用throws关键字)。它们是`Exception`类及其子类(除了`RuntimeException`及其子类)。 - 例如:`IOException`、`SQLException`等。 2. **检查型异常(Unchecked Exceptions)**: - 也称为运行时异常(Runtime Exceptions),这些异常在编译时不强制要求处理,通常由程序逻辑错误引起。它们是`RuntimeException`类及其子类。 - 例如:`NullPointerException`、`ArrayIndexOutOfBoundsException`、`ArithmeticException`(如除以零)等。 3. **错误(Errors)**: - 这些是`Error`类及其子类,表示严重的问题,通常与程序无关,而是系统错误或资源耗尽等。应用程序通常不捕获这些错误,因为它们很难恢复。 - 例如:`OutOfMemoryError`、`StackOverflowError`等。 在try-catch块中,我们可以捕获任何`Throwable`及其子类的对象(包括`Exception``Error`)。但通常,我们只捕获那些我们能够处理的异常(主要是`Exception`及其子类,特别是检查型异常部分运行时异常),而错误(`Error`)通常不应该被捕获,因为程序在错误发生时往往无法正常恢复。 引用[4]中有一个例子,它捕获了`NumberFormatException`,这是一个运行时异常检查型异常): ```java try { String str = "yinhai"; int a = Integer.parseInt(str); // 这里会抛出NumberFormatException System.out.println("数字" + a); } catch (NumberFormatException e) { System.out.println(e.getMessage()); } ``` 另外,我们可以在一个try块后面跟随多个catch块,以捕获不同类型的异常(引用[2])。注意,捕获异常的顺序应该是从具体到一般(即先捕获子类异常,再捕获父类异常),否则会导致编译错误。 例如: ```java try { // 可能产生多种异常的代码 } catch (FileNotFoundException e) { // 处理文件未找到异常 } catch (IOException e) { // 处理其他IO异常 } catch (Exception e) { // 处理其他异常 } ``` 最后,引用[5]提到,在方法内部使用try-catch处理异常后,就不需要再用throws声明相同的异常了,因为异常已经被处理掉了。 总结:Java try-catch可以捕获的异常类型包括: - 检查型异常(必须处理) - 检查型异常(运行时异常,可选择处理) - 错误(Error,通常不捕获) 但实际编程中,我们主要捕获那些我们能够处理的异常,而错误一般不予捕获。 现在,我们根据用户的问题,给出一个结构化的回答。</think>### Java try-catch 可捕获的异常类型详解 在 Java 中,`try-catch` 语句可以捕获任何继承自 `Throwable` 类的异常类型,主要分为三大类: #### 1. **检查型异常 (Checked Exceptions)** - **特**:编译器强制要求处理的异常,必须显式捕获或声明抛出 - **继承关系**:`Exception` 的直接子类(除 `RuntimeException` 外) - **常见类型**: - `IOException`(输入输出异常) - `SQLException`(数据库操作异常) - `ClassNotFoundException`(类未找到异常) - `FileNotFoundException`(文件未找到异常) - **处理要求**:必须通过 `catch` 捕获或使用 `throws` 声明[^1][^3] #### 2. **检查型异常 (Unchecked Exceptions)** - **特**:运行时异常,编译器不强制处理 - **继承关系**:`RuntimeException` 及其子类 - **常见类型**: - `NullPointerException`(空指针异常) - `ArrayIndexOutOfBoundsException`(数组越界异常) - `ArithmeticException`(算术异常,如除以零) - `NumberFormatException`(数字格式异常,如 `Integer.parseInt("abc")`)[^4] - `IllegalArgumentException`(法参数异常) - **处理建议**:应通过代码逻辑预防,但也可用 `try-catch` 捕获[^2][^4] #### 3. **错误 (Errors)** - **特**:严重系统级错误,通常无法恢复 - **继承关系**:`Error` 及其子类 - **常见类型**: - `OutOfMemoryError`(内存耗尽错误) - `StackOverflowError`(栈溢出错误) - **处理建议**:通常**不推荐**捕获,应解决根本问题[^1][^3] ### 异常捕获机制要 1. **多类型捕获** 一个 `try` 块可接多个 `catch` 子句,按顺序匹配异常类型: ```java try { // 可能抛出异常的代码 } catch (FileNotFoundException e) { // 处理文件未找到 } catch (IOException e) { // 处理其他IO异常 } catch (Exception e) { // 兜底处理其他异常 } ``` 2. **捕获顺序规则** 子类异常必须放在父类之前(如先 `FileNotFoundException` 后 `IOException`),否则编译错误[^2][^4]。 3. **通用捕获方式** 使用 `Exception` 可捕获所有异常(含 `RuntimeException`),但会屏蔽具体异常信息: ```java catch (Exception e) { System.out.println("捕获到异常: " + e.getMessage()); } ``` 4. **finally 块** 无论是否发生异常都会执行,常用于资源清理(如关闭文件流)[^1][^3]: ```java finally { if (file != null) file.close(); } ``` ### 异常处理最佳实践 1. **精确捕获**:优先捕获具体异常类型,避免过度使用 `Exception`[^5] 2. **避免空 catch**:至少记录异常信息(如 `e.printStackTrace()`) 3. **资源管理**:使用 `try-with-resources`(Java 7+)替代 finally 手动关闭 4. **异常传递**:方法内已处理异常时,无需再用 `throws` 声明[^5] > 示例:捕获 `NumberFormatException`(引用自[^4]) > ```java > try { > String str = "yinhai"; > int a = Integer.parseInt(str); // 抛出NumberFormatException > } catch (NumberFormatException e) { > System.out.println("转换失败: " + e.getMessage()); > } > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值