毕25-第五天(day10)-面向对象(异常)

本文深入解析Java异常处理机制,包括finally语句的作用、自定义异常的创建、异常体系结构及异常处理原则。通过实例演示了如何在代码中有效使用try、catch、throw和throws关键字。
  • finally关键字

在下面的例子中,finally中语句,以及后面的输出over语句都执行了:

class FuShuException extends Exception{
	FuShuException(String msg){
		super(msg);
	}
}

class Demo{
	int div(int a,int b)throws FuShuException{
		if(b<0) {
			throw new FuShuException("除数为负数");
		}
		return a/b;
	}
}

class Test{
	public static void main(String[] args){
		Demo d = new Demo();
		try {
			int x = d.div(4, -1);
			System.out.println("x="+x);
		}catch(FuShuException e){
			System.out.println(e.toString());
		}finally {
			System.out.println("finally");	//finally语句中存放的是一定会被执行的语句。
		}
		System.out.println("over");
	}
}
/*
 d.div(4, 1);输出:
x=4
finally
over
 d.div(4, -1);输出:
除数为负数
finally
over
*/

但是如果在catch中“System.out.println(e.toString());”的语句后面又return语句,即主函数的剩下部分不会执行,但是finally内的语句依然会执行,此时输出:

除数为负数

finally

finally代码块用来定义一定执行的代码,通常用于关闭资源。如下面示例的数据库关闭:

class NoException extends Exception{
}

public void method()throws NoException {
	//连接数据库;
	//数据操作;	//throw new SQLException();
	//关闭数据库;	//该动作无论数据操作是否成功,一定要关闭资源,否则会造成资源浪费。所以使用下面的finally语句块来进行关闭数据库操作。
	
	try {
		连接数据库;
		数据操作;		//throw new SQLException();
	}catch(SQLException e){
		会对数据库进行异常处理;
		throw new NoException();    //这里抛出一个新的表明没有能够成功操作数据库的异常,因为如果抛出SQLException异常的话,调用者也不知道如何处理,返回操作未成功异常,调用者可以做出相应的处理。
	}finally {
		关闭数据库;
	}
}

异常处理语句的几种格式:

//第一种格式:
try {
	
}catch() {
	
}
//第二种格式:
try {
	
}catch() {
	
}finally {
	
}
//第三种格式:
try {
	
}finally {
	//通常用来关资源;
}

记住一点:catch是用于处理异常,如果没有catch语句块,就表明异常没有被处理过。如果该异常是检测时异常,则必须在函数上声明(抛出)。

  • 子父类覆盖中异常的特点

异常在子父类覆盖中的表现:

1、子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。

class AException extends Exception{
	
}
class BException extends Exception{
	
}
class CException extends Exception{
	
}
class Fu{
	void show()throws AException{
		
	}
}
class Zi extends Fu{
	void show()throws AException{    //抛出AException或BException,即父类抛出的异常或父类异常的子类;
                                     //这是因为如果抛出的是父类异常或其子类,则在调用子类方法的地方,使用catch就可以捕获该异常,也利用了多态的特性:AException e = new AException();/AException e = new BException();
		
	}
}
class Test{
	void function(Fu f) {
		try {
			f.show();    //调用子类覆盖过后的show方法
		}catch(AException e) {
			
		}
	}
}
class Main{
	public static void main(String[] args) {
		Test t = new Test();
		t.function(new Zi());    //利用到了多态的特性:Fu f = new Zi();
	}
}

2、如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

3、如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可能抛出异常;如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。

  • 异常的总结(全面)

异常是什么:异常是对问题的描述,将问题进行对象的封装。

异常部分体系:

Throwable
    |--Error
    |--Exception
        |--RuntimeException

异常体系的特点:异常体系中的所有类以及建立的对象都具有可抛性,也就是说可以被throw和throws关键字做操作;只有异常体系具备这个特点。

throw和throws的用法:throw定义在函数内,用于抛出异常对象;throws定义在函数上,用于抛出异常类,可以抛出多个异常,多个异常之间用逗号隔开。

当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则会编译失败。但是注意:RuntimeException除外,也就是说函数内如果抛出的是RuntimeException,函数上可以不用声明。

如果函数声明了异常,调用者需要进行处理,处理方法可以throws可以try。

异常有两种:一种是编译时被检测异常,该异常在编译时,如果没有处理(没有throws也没有try),则编译失败;一种为运行时异常(编译时不检测),该异常的发生建议不处理,让程序停止,需要对代码进行修正。

finally:finally中定义的通常是关闭资源代码,因为资源必须及时释放;finally只有一种情况不会执行,当执行到System.exit(0);时,finally不会执行,因为这时直接跳出虚拟机,不同于return。

自定义异常:定义类继承Exception或者RuntimeException。一是为了让该自定义类具备可抛性;另一个是让该类具备操作异常的共性方法。

当要定义自定义异常的信息时,可以使用父类已经定义好的功能,将异常信息直接传递给父类的构造函数:

class MyException extends Exception{
    MyException(String message){
        super(message);
    }
}

自定义异常是按照Java的面向对象思想,将程序中出现的特有问题进行封装。

异常的好处:一是将问题进行封装;二是将正常流程代码和问题处理代码相分离,便于阅读。

异常的处理原则:

1、处理方式有两种:try或者throws。

2、调用到抛出异常的功能时,抛出几个就处理几个,一个try对应多个catch。

3、有多个catch时,父类的catch放到最下面。

4、catch内需要定义针对性的处理方式,不要简单的定义printStackTrace、输出语句,也不能不写;

当捕获到的异常,本功能处理不了时,可以在catch继续抛出:

try{
    throw new AException();
}catch(AException e){
    throw e;
}

如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,再抛出和该功能相关的异常;或者异常可以处理,将异常产生和本功能相关的问题提供出去,让调用者知道并处理。

try{
    throw new AException();
}catch(AException e){
    //对AException处理
    throw new BException();
}

注意,再子父类覆盖时:

1、子类抛出的异常必须是父类的异常,或其子类或子集;

2、如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛出去(throws)。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值