异常处理机制

本文探讨了在学习过程中如何运用面向对象思维解决遇到的问题,深入解析了异常的概念及其体系,包括异常的分类、异常的声明与抛出、异常的捕获与处理,以及自定义异常的定义方式和应用实例。

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

小感悟:

在学习的时候,难免会碰到各种问题,我可以用面向对象的思维来理解这个状况:

碰到问题,我们能解决吗?能解决,就try ……catch  ,不能解决,就找对象(面向对象),然后——throw ,哈哈!

—————————————————————————————————————————————————————————————————————

【异常】 ——简单理解就是:不正常。这些不正常情况发生在【运行时期】。

  

【异常体系的由来】

       程序运行时总会出现一些不正常的情况。Java语言对这些不正常情况也进行了描述,并对这些不正常进行了对象的封装。也就是说异常可以理解为:描述不正常情况的对象。【异常情况有多种,都需要分别描述,意味着异常情况应该会有一个体系】多个异常具备共性不断的向上抽取。就形成了异常体系。


 【如下图所示:】

【Throwable :可抛出】

    |

    |--Error——有JVM从底层抛出来的问题,通常不需要处理。得修改程序。

    |

    |--Exception——可以定义针对的处理方式对该种情况进行处理。


无论是Error 还是Exception,他们的子类都一个特点:子类名的后缀都是父类名。 这个异常体系最大的特点:就在于该体系中的类和对象都具备可抛性。


【throws 和 throw两者区别】

throws用在函数上,用于功能声明异常,后面抛出的是异常类可以抛出多个,只要用逗号隔开即可。

throw只能用在函数内,用于抛出异常对象,额外特点,一旦执行,具有结束函数的功能。


【异常时可以处理的】——【处理方式】

1. 声明抛出。告诉调用者功能会有问题。通过throws关键字对问题声明在功能上。

2. 进行捕捉。可以使用针对性的捕捉代码块儿完成。

try

{

       //需要被检测的代码。

}

catch(异常类  变量)//该变量用于检测抛出的异常对象。

{

       //异常处理代码

}

finally

{

       //一定会被执行的代码

 

}

【finally】

       一定会被执行的代码。 主要用于释放资源。无论是否发生异常,有些动作一定要执行,那么这些动作定义在finally代码块儿中。

【注意:】System.exit(0);退出JVM,这时finally也不会执行。

在进行异常捕捉时,代码块的不同组合情况。

1. try   catch   finally

2. try   catch    // 没有需要一定被执行的代码——不需要关闭资源的动作。

3. try    finally // 异常并没有被处理,但是却涉及到了资源的调用,资源需要被关闭。   所以就有了,将异常进行对外声明,因为没有catch,但是资源是在功能内部打开的,必须要功能内部关闭,就有了try 和 finally 的组合。

【自定义异常:】

       对于常见的不正常情况,Java都有对应的描述,比如角标越界,或者空指针等。

       对于自定义的程序中的出现的特有问题,Java并没有给出对应的描述。

       这时需要我们队异常进行处理。

 

       【定义方式:】

        1. 定义一个类,对问题进行描述;

        2.必须要让这个类继承异常类,具备可抛性。


【代码体现】

class FuShuException extends Exception{
	private int num;
	
	FuShuException(){
		super();
	}
	
	FuShuException(String message){
		super(message);
	}
	FuShuException(String message , int num){
		super(message);
		this.num = num;
		
	}

	FuShuException(int num){
		this.num = num;
	}
	public int getNum(){
		return num;
	}
}
class Demo11{
	int div(int a , int b) throws FuShuException , ArithmeticException{
		if (b < 0)
			throw new FuShuException("错误,不允许 除数是负数!该负数是——>" +b);
		if (b == 0)
			throw new ArithmeticException("完了,被零除了!");
		return a/b;
	}
}
public class ExceptionDemo3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Demo11 d = new Demo11();
		try {
			int x = d.div(4, -1);
			System.out.println("x = " + x);
		} catch (FuShuException e) {
			// TODO: handle exception
			System.out.println("message : " + e.getMessage());//异常信息
			System.out.println("toString : " + e.toString());//异常的名字 + 信息
			System.out.println("负数是 :" + e.getNum());
			e.printStackTrace();// 打印异常的信息 和 名字 和 位置
		}catch (ArithmeticException e){
			System.out.println("message : " + e.getMessage());
			System.out.println("toString : " + e.toString());
			e.printStackTrace();
		}
		System.out.println("over");
	}
}

细节:

1. 定义功能,功能内部因为传入的参数问题,导致了功能 会出现问题。这时为了解决这个问题, 通常都会将问题通过throws声明在函数上。

       目的:为了调用者在使用这个功能的时候,能明确处理方式。

      也就是说:throws抛出的目的是为了让调用者预先定义好问题的处理方式。

2.  如果一个功能抛出多个异常。那么在调用该功能时,需要有多个catch进行每一个异常的针对性处理;

      如果多个catch中有父类异常,父类异常一定要定义在最下面。否则编译失败!

3. 特殊部分:

       函数内抛出异常,函数上一定要用throws标示,否则编译失败。

       调用到声明异常的函数,要进行声明throws声明抛出,或者trycatch捕捉。

异常分两种:

       1.编译时被编译器检测的异常。

              通常要编写针对性大的处理代码进行处理。

       2.编译时不被检测的异常,这种异常出现,编译时期是不在检查之列。成为运行时异常。

         也就是说函数内throw抛出运行时异常,不需要在函数上声明。即使声明了,

         调用者也不用一定给出预先处理方式,因为它不会导致编译失败。

        通常,不编写针对性的代码进行处理,一旦发生,就让程序停掉。

        为了对代码进行修正。


【区分方式】

Exception中一个特殊的子类:RuntimeException就是运行时异常。RuntimeException和其子类都不需要编译时检测。

意味着:我们在自定义异常时,可以继承Exception,称为运行时异常。

————————————————————————————————————————————————————————————————————

异常覆盖中的细节:

1.子类在覆盖父类时,如果父类中被覆盖的方法抛出了异常,

那么子类覆盖的方法,只能抛出相同的异常,或者该异常的子类。++

2. 如果父类的被覆盖方法抛出了多个异常,子类在覆盖时,只能抛出这些异常的子集。

【3.重点掌握】 如果被覆盖的方法没有抛出异常,子类也不允许抛出异常。如果子类中真的出现异常,只能在子类方法内进行try处理,绝对不允许throws声明。 万一处理不了呢?你可以选择抛出运行时异常。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值