Java异常详解

本文详细介绍了Java中的异常处理机制,包括异常的基本概念、分类,如Error和Exception,以及如何使用try-catch-finally进行异常捕获和处理。此外,还探讨了throw关键字用于手动抛出异常,并讲解了自定义异常的实现方式。通过实例代码,帮助读者深入理解Java异常处理的各个方面。
摘要由CSDN通过智能技术生成

基本介绍

背景

  1. 在介绍异常之前,我们先来看看以下几种常见的异常
	除以0
System.out.println(15/0);
//Exception in thread "main" java.lang.ArithmeticException: / by zero
	数组下标越界
int[] arr = {1,2,3};
System.out.println(arr[12])
//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 12
	访问空对象
String n = null;
System.out.println(n.length());
//Exception in thread "main" java.lang.NullPointerException
  1. 防御式编程
    错误在代码中是客观存在的,我们需要在出现问题时能够通过某种手段来提醒程序员。这里有两种主要的方式:
    1. LBYL(Look Before You Leap),在操作之前作充分的准备
    2. EAFP: It’s Easier to Ask Forgiveness than Permission. 事后获取原谅比事前获取许可更容易". 也就是先操作, 遇到问题再处理,EAFP即为我们要讨论的异常的核心思想
LBYL风格式代码
int x = 1;
      if(x < 0){
          //提醒x小于0;
      }else if(x == 0){
          //提醒x等于0
      }
    }

概念

java语言中,将程序执行中发生的不正常情况称为异常,(语法错误和拼写错误不是异常,在java中这些错误被称为Error)

异常分类

异常事件分类

  1. Error(错误),Java虚拟机无法解决的严重问题,如:jvm系统内部错误,资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of memory),Error是严重错误,程序会崩溃.。

  2. Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等,Exception可分为两大类:运行时异常[程序运行时发生的异常]和编译时异常[编程时,编译器检查出的异常]

  3. Throwable

    Error

    栈溢出错误、堆溢出错误等等

    异常

    编译异常

    IOException

    ClassNotFoundException

    CloneNotFoundException

    运行异常

    数组越界、空指针异常、计算异常等等

异常处理

try-catch-finally

  1. 基本语法:

try{
有可能出现异常的语句 ;
}[catch (异常类型 异常对象) {
} … ]
[finally {
异常的出口
}]

try代码块中存放可能出现异常的代码
catch代码块中存放的是对出现的异常处理的代码
finally中的代码块用于处理善后工作,会在最后执行

  1. 异常捕获细节
    1. try代码块中如果异常发生了,则不会执行try代码块中异常语句之后的代码,直接进入catch代码块

    int[] arr = {1,2,3};
    try {
    int n = arr[4];
    System.out.println(“这里的代码不会执行”);
    } catch (ArrayIndexOutOfBoundsException e) {
    e.printStackTrace();
    } finally {
    //释放资源
    }
    以上代码存在数组越界异常,无法执行第四行的输出代码

    1. 如果异常没有发生,则顺序执行try的代码块,不会进入到catch

    int[] arr = {1,2,3};
    try {
    int n = arr[2];
    System.out.println(“这里的代码会执行”);
    } catch (ArrayIndexOutOfBoundsException e) {
    System.out.println(“这里的代码会执行”);
    } finally {
    //释放资源
    }
    以上代码没有异常,try中的代码会全部执行,catch中的代码不会执行

    1. finally代码块中的语句一定会执行,所以finally代码块中通常执行某些资源的释放和关闭,尽量不要在finally代码块中方return语句

    int[] arr = {1,2,3};
    try {
    int n = arr[4];
    System.out.println(“这里的代码会执行”);
    } catch (ArrayIndexOutOfBoundsException e) {
    e.printStackTrace();
    return 10;
    } finally {
    //释放资源
    return 20
    }
    以上代码发生了异常会执行catch代码块中的return 10语句,但finally是最后一定执行的,所以最终会返回20

    1. 异常处理流程
    • 程序先执行 try 中的代码
    • 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
    • 如果找到匹配的异常类型, 就会执行 catch 中的代码
    • 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
    • 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
    • 如果上层调用者也没有处理的了异常, 就继续向上传递.
    • 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止

throw

除了 Java 内置的类会抛出一些异常之外, 也可以手动抛出某个异常. 使用 throw 关键字完成这个操作

public static void main(String[] args) { 
 System.out.println(divide(10, 0)); 
} 
public static int divide(int x, int y) { 
 if (y == 0) { 
 throw new ArithmeticException("抛出除 0 异常"); 
 //可以认为设定异常输出信息
 } 
 return x / y; 
} 

在处理异常时,为了显示的知道异常发生的位置,我们可以用throws将发生的异常类型在方法声明中显示`

public static int divide(int x, int y) throws ArithmeticException { 
 if (y == 0) { 
 throw new ArithmeticException("抛出除 0 异常"); 
 } 
 return x / y; 
} 

自定义异常

在实际的业务开发中,我们可能需要对异常类进行拓展,创建满足我们实际情况中会发生的异常

  • 在自定义异常时,我们通常将异常类型定义RuntimeException而不定义为编译异常。
int x = -1;
     if(x<=0){
         throw new RuntimeException("数字不是正数");
         //新定义的异常中的描述信息可以随意设定
     }
        System.out.println("数字为正数");
    }
  • 我们也可以自定义一个异常类`
public class TestDemo {
    private static final String userName = "admin";
    public static void main(String[] args) {
        login("Admin");
    }
    public static void login(String name){
        if(!name.equals(userName)){
            throw new UserNameException("用户名错误!");
        }
    }
}
class UserNameException extends RuntimeException{
    public UserNameException(String message) {
        super(message);
    }
}
//最终运行结果会提示用户名错误!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

囚蕤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值