【JavaSE_学习笔记】异常体系

本文深入讲解Java异常体系,包括异常的分类、处理方式及自定义异常等核心概念,并通过实例演示异常处理的具体应用。

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

【JavaSE_学习笔记】异常体系

Java程序也会出现许多不正常的情况,Java使用了许多类描述这些不正常的情况,这些类堆积在一起就形成了Java的异常体系
———| Throwable 所有错误与异常的父类
—————| Error 错误,错误一般都是由于jvm或者是硬件引发的问题。一般都不会通过代码处理错误
—————| Exception 异常, 异常我们是需要通过代码去处理的
这里写图片描述
Throwable常用的方法:
  1.toString() 返回此throwable的简短描述(全路径名称)
  返回的是用于描述该异常情况的类的完整类名如:java.lang.Throwable
  2.getMesage() 返回创建Throwable对象的时候传入的消息字符串
  3.printStackTrace()
  打印异常的栈信息  可以追踪到异常的行号
Error:错误一般都是由于jvm或者硬件引发的问题,一般都不会通过代码去处理
Exception:如果程序出现异常,一般就需要通过代码处理
 如果不正常情况的消息是以Error结尾的,则代表这是一个错误
 如果不正常情况的消息是以Exception结尾的,则代表这是一个异常
   运行时异常: RunTimeException及其子类
   编译时异常: 非运行时异常,受检异常

异常的处理方式:

  方式一:捕获处理
    格式:

try{可能会发生异常的代码
}catch(异常的类型 变量名){
    异常处理的代码;
}

举例:

public class Demo2 {
    public static void main(String[] args) {
        int a=10;
        int b=0;
        try {
            System.out.println(a/b);
        } catch (ArithmeticException e) {
            System.out.println("被除数不能为零!");
            System.out.println("下次注意");
        }
        System.out.println("异常被处理");
    }
}

结果:

被除数不能为零!
下次注意
异常被处理

注意:
  1.如果一个try块的的代码出现了异常经过处理后,那么try-catch块外面的代码可以正常执行;
  2.如果一个try块中出现了异常的代码,那么在try块中出现异常代码后的所有代码都无法正常执行;
  3.一个try块后可以跟有多个catch块,即一个try块可以捕捉多种异常的类型;
  4.一个try块后面可以跟多个catch块,但捕捉的异常类型必须按照从小到大进行捕捉,否则后面的代码无法执行
举例:

public class Democracy {
    public static void main(String[] args) {
        div(4,0,null );
    }
    public static void div(int a, int b,int[] arr){
        int c = 0;
        try{
             System.out.println("数组的长度:"+ arr.length);  // 
             c = a/b;    // jvm发现除数为0的时候,就会创建一个异常的对象。
        }catch(ArithmeticException e){   //捕获的异常类型 
            System.out.println("出了算术异常...");
            e.printStackTrace();
        }catch(NullPointerException e){
            System.out.println("出现了空指针异常....");
        }catch(Exception e){    // new NullPointerException();  Exception之所以可以捕获任意类型的异常,是因为Exception是所有异常类的父类。
            System.out.println("我是急诊室,能治百病...");

        }
        System.out.println("结果:"+ c);
    }
}

结果:

出现了空指针异常....
结果:0

  方式二:抛出处理
举例:

class Demo2 
{
    public static void main(String[] args) 
    {
        try{
            div(4,0,null);
        }catch(Exception e){
            System.out.println("哎呀,出错了...");
        }
    }

    public static void div(int a , int b,int[] arr) throws Exception ,NullPointerException{
        if(b==0){
            throw new Exception();//抛出一个异常对象。
        }else if(arr==null){
            throw new NullPointerException();
        }
        int c  = a/b;
        System.out.println("结果:"+ c);
    }

}

注意:
   1. 如果一个方法的内部抛出了一个编译时异常对象,那么必须 要在方法声明抛出;
  2. 如果调用了一个声明抛出编译时异常类型的方法,那么调用者必须要进行处理,否则编译报错;
  3. 一个方法如果遇到了throw关键字,那么该方法会马上停止执行;
  4. 在一个种情况下只能抛出一种异常对象。
throw与throws区别:
  1. throw关键字是用于在一个方法的内部抛出异常对象的,throws是用于在方法上声明抛出异常类型的。
  2. throw关键字后面跟的是一个异常的对象,throws后面跟的是异常的类型。
  3. throw关键字一次只能抛出一个异常对象,throws一次可以声明抛出多种异常类型。

什么时候使用抛出处理?什么时候使用捕获处理?
  如果需要通知调用者出了异常,那么则需要使用抛出处理。
  如果与用户直接打交道的代码就使用捕获处理,千万不能抛出,一旦抛出就抛给了用户。

  运行时异常:如果一个方法内部抛出了一个运行时异常对象,方法声明可以声明抛出也可以不声明抛出,如果调用了一个声明抛出运行时异常类型的方法,调用者可以处理也可以不处理
  编译时异常:方法必须要声明抛出,如果调用了一个声明抛出编译时异常类型的方法,调用者必须要处理

自定义异常类
class NoIPException extends Exception{

    public NoIPException(String message){
        super(message); //调用了父类一个参数的构造函数
    }
}



class Demo4 
{
    public static void main(String[] args) 
    {
        try{
            feiQ(null);
        }catch(NoIPException e){
            e.printStackTrace();
            System.out.println("马上就插上网线!!");
        }
    }

    public static void feiQ(String ip) throws NoIPException{
        if(ip==null){
            throw new NoIPException("没有插网线啊,小白");
        }
        System.out.println("好友列表是....");
    }   

}
finally块

使用前提:必须要配合try块使用,不能单独使用
finally块的代码在任何情况下都可以执行(不论catch块中的代码有没有执行)只有在jvm退出的情况下才不会执行
举例:

class Demo6 
{
    public static void main(String[] args) 
    {
        try{
            int c = 4/2;
            System.out.println("结果:"+ c);
            //return;
            //System.exit(0); // 0表示正常退出jvm,非0表示异常退出jvm。 
        }finally{
            System.out.println("finally块的代码执行了...");
        }
    }
}
try块的表现形式:

  方式1: 适用于没有资源文件释放,只需要处理异常的代码使用

try{ 
    可能发生异常的代码 
    } catch( 异常类的类型 e){
    异常的处理代码..
}   

  方式2: 适用于既有资源释放也需要处理异常的代码去使用

try{ 
    可能发生异常的代码 
    } catch( 异常类的类型 e){
    异常的处理代码..
}   finally{
     释放资源的代码;
}

  方式3: 只需要 释放资源文件,不需要处理异常的代码去使用

try{ 
    可能发生异常的代码 
    } finally{
 释放资源的代码;
}

  方式4:必须都是平级异常

try{可能出现异常的代码;
    }catch(异常类名1|异常类名2|...){
    处理代码;
}

注意:
  1)子类在重写父类中的方法的时候,如果父类中方法有抛出异常,那么子类重写的这个方法,抛出异常不能够比父类中该方法异常大
  2)子类继承父类,要重写父类中的方法的时候,如果本身父类中该方法没有异常,那么在子类中重写该方法的时候,不能抛出异常,只能捕获异常

面试题:如果catch里面有return语句,那么finally中的代码还会执行吗?如果可以,是在return前执行还是return后执行?
   会执行;并且在return 前执行!

public class Demo4 {
    public static int a1=10;
    public static void main(String[] args) {
        System.out.println(getInt());
    }


    //方法
    private static int getInt() {
        int a=20;
        try{
            System.out.println(a/0);
            a = 20 ;
        }catch(ArithmeticException e){
            a = 30 ;
            System.out.println("a为:"+a);
            return a1 ;
            /**
             * 代码走到这里,return a,return 30 ,在这里形成了一个方法返回路径
             * 但是,finally中代码只有在Jvm退出了,才不会执行,所以a = 40 ;
             * 但是,由于之前已经返回路径,代码就要执行到return 前;
             */
        }finally{
            a1 = 40 ;
            System.out.println("a1为:"+a1);
        }
        return 0;

    }
}

结果:

a:30
a1为:40
10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值