异常机制

本文深入探讨Java异常处理机制,包括异常的分类如运行时异常和编译时异常,异常处理的方法如try-catch-finally,以及如何使用throws和throw进行异常的声明与抛出。同时,介绍了自定义异常的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 异常机制

Throwable 类是 Java 语言中所有错误或异常的超类。

  • 2个子类
  •  Error:错误  严重错误,程序员无法解决
    
  •  Exception:异常 ,是一种程序(代码)错误,程序员是可以解决的
    

(异常本身就是一个类)
异常机制的本质就是当程序出现错误,程序安全退出的机制

Throwable
Exception
error
RuntimeException运行时异常
CheckedException编译时异常
UncheckedException

error是虚拟机崩溃,它是由JVM产生和抛出的,我们不需要管

2 RuntimeException运行时异常

代码执行过程中出现的异常,不需要throws异常

2.1 常见的运行时异常

  • NullPointerException 空指针异常
  • ArrayIndexOutOfBoundsException 数组下标越界异常
  • ArithmeticException 算术运算异常
  • InputMismatchException 类型匹配异常
  • ClassCastException 类型转换异常

2.2 NullPointerException空指针异常

public class Test04 {
     public static void main(String[] args) {
          int[] arr = null;
          System.out.println(arr.length);
     }
}

2.3 ArithmeticException除0异常

public class Test04 {
     public static void main(String[] args) {
          int a = 0;
          int b = 1;
          System.out.println(b/a);
     }
}

2.4 IndexOutOfBoundsException数组越界异常

int[] arr = {1, 2, 3};
System.out.println(arr[3]);

2.5 ClassCastException异常

当对象转换为不属于实例的子类时发生(当强制转换很过分的时候)

public class Test04 {
  public static void main(String[] args) {
          Animal c = new Cat();
          Animal d = new Dog();
          c = (Cat)d;
     }

}

class Animal{}

class Cat extends Animal{}

class Dog extends Animal{} 

3 编译时异常

代码没有执行就报错,和语法错误没有关系
Exception及其子类(不包含运行时异常),统称为编译时异常,编译时异常可被检查出,要么用try——catch捕获异常要么就用throws声明异常。
比如IOException,编译时就要求抛出。

3.1 try-catch-finally(finally可省略)

try代码块中放可能出现异常的代码,表示尝试执行可能出现异常的代码
catch是对异常的捕获,
finally:表示最后一定会执行的意思
throws:表示声明可能会抛出
throw: 表示一定会抛出
在这里插入图片描述
try-catch-finally 机制中,catch可能会执行,finally的代码一定会执行,除非在try或catch中加System.exit(0);退出虚拟机操作
try-finally机制中,因为没有catch,没有捕获异常,所以默认是JVM抛出,finally只是为了释放资源。
try-catch一般不解决异常,只是为了不影响后面代码的运行

3.2 面试题:final,finalize,finally这三者区别?

  • final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
    
  • finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些**关闭资源**的代码。
    
  • finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System的gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾。   
    

4 抛出异常(消极处理异常的方案)

4.1 throws

**编译时异常有两种处理方式:要么try……catch;要么抛出异常
throws:声明一个可能的异常,并把这个异常抛上一级,谁调用,谁处理.

  • 如果将异常抛给上一级,一旦代码出现异常,则异常后面的代码不再执行;

4.2 throw

主动抛出一个异常对象,表示一定会出现异常

  • 格式:出现在方法体中
  • 注意1:throw后面不能出现代码
  • 注意2:throw经常出现在catch中,将捕获的异常再次转义,抛一个更加友好或者范围更小的异常出去,有利于上级调用者处理异常
    
  • 注意:如果异常发生地方有好几处,其实真正的异常一般只有一个,在最里面,也就是控制台报错的第一行
    
  •  注意:如果异常一直向上声明抛出,最后会抛给JVM,那么我们的代码就无法正常执行了
    
  •  注意:我们一般向外声明并且抛出的异常都是编译时异常
    
  •  注意:一个方法可以向外声明多个异常,中间用逗号隔开
    
  •  注意:可以向外声明编译时异常,也可以声明运行时异常
    
  • 如果声明的是编译时异常,那么谁调用,谁必须处理(要么抛,要么try..catch..)
    
  • 如果声明的是运行时异常,那么谁调用,谁处理  
    
  •  注意: 如果方法抛出的是父异常,那么上一级处理的时候,异常类型至少要>=抛出的异常   
    
  •  注意:如果一个方法抛出了多个异常,上一级处理的时候,可以将这些异常合并为1个异常(这些小异常必须是某一个大异常的子类)
    
  •  注意:用户从前台传进来的数据,程序员需要对这些数据做验证处理
    
  •      验证模式1:数据格式验证       前台做处理
    
  •      验证模式2:数据(格式和准确性)验证   后台做处理
    

4.3 throws和throw的区别

  1. 格式
    throws声明在方法头部
    throw声明在方法体
  2. 异常抛出的几率不同
    throws表示有可能会抛出异常
    throw表示一定会抛出异常
  3. throws抛出的是异常类
    throw抛出的是异常的对象
  4. 个数
    throws可以抛出多个异常
    throw只能抛出一个异常

System.err.println();打印的内容为红色字体。

5. 异常的一些其他的知识

子类声明异常的范围不能超过父类声明异常的范围
1. 父类没有声明异常,子类重写方法也不能声明异常,不是重写方法可以;
2. 父类如果抛出异常,子类只能抛出父类的异常或者该异常的子类
有时候我们会捕获一个异常,然后再抛出一个异常

// 自定义异常
class DenominatorZeroException extends Exception {
     public DenominatorZeroException() {}
     public DenominatorZeroException(String msg) {
          super(msg);
     }
}

// 计算器类
class Calculator {
     // 除法运算
     public static int division(int num, int den) throws DenominatorZeroException {
          int result = 0;
          try {
              result = num/den;
          }
          catch(ArithmeticException e) {
              // 抛出一个更详细的异常
              throw new DenominatorZeroException("分母不能为0");
          }
          return result;
     }
}

public class ExceptionTest07 {
     public static void main(String[] args) {
          try {
              // 两个数做除法运算,可以会发生算数异常
              Calculator.division(5, 0);
          } catch (DenominatorZeroException e) {
              e.printStackTrace();
          }
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值