异常


1.异常的继承体系

Throwable
|--Error
通常出现重大问题如:运行的类不存在或者内存溢出等。
不编写针对代码对其处理
|--Exception 
在运行时出现的不正常情况,可以通过try catch finally

异常的特性:异常类和异常对象都可以被抛出,他们都具备可抛性
可抛性的前提:要继承异常类

ExceptionError的子类名都是以父类名作为后缀。
JAVA在设计异常体系时将容易出现的情况都封装成了对象

2.Throwable中的方法
getMessage()
获取异常信息,返回字符串。
toString()
获取异常类名和异常信息,返回字符串。
printStackTrace()    (JVM的默认处理方法)
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
printStackTrace(PrintStream s)
通常用该方法将异常内容保存在日志文件中,以便查阅

代码示例:
class ChuFa
{
	int a,b;
	int chu(int a,int b)
	{
		return a/b;
	}
}
class ExceptionDemo 
{
	public static void main(String[] args) 
	{
		ChuFa f = new ChuFa();
		try
		{
			int x = f.chu(5,0);
			System.out.println(x);	
		}
		catch (Exception e)//定义一个异常类来接收封装了的异常对象
		{
			System.out.println("不能除零!");
			System.out.println(e.getMessage());
			System.out.println(e.toString());
			e.printStackTrace();//JVM默认情况下的处理方法
		}
		System.out.println("over");
	}
}


3. throw和throws
作用:
throws用于标识函数暴露出的异常。
throw用于抛出异常对象。
throws与throw的区别:
thorws用在函数上,后面跟异常类名。
throw用在函数内,后面跟异常对象。
在函数内抛出(throw)什么异常,就要在函数上标示(throws)出什么异常

4.使用try...catch捕获异常
格式:
try
{
需要检测的代码;
}
catch(异常类  变量)
{
异常处理代码;
}
finally
{
一定会执行的代码;
}

5.异常的处理方式有两种:
1,捕获:使用try...catch语句捕获
2,抛出:使用throws抛出

定义异常处理时,什么时候定义try,什么时候定义throws呢?
功能内部如果出现异常,如果内部可以处理,就用try;
如果功能内部处理不了,就必须声明出来,让调用者处理。

多异常的处理注意事项:
1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。 如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
3,不会出现捕获到多个异常的情况,因为当捕获到异常时,语句直接跳转到catch代码块,在异常语句之后的语句将不会被运行,当找到对应的catch代码块时,该代码块处理完异常后,程序结束, 之后的catch代码块将不被运行。

7.自定义异常:
当开发时,项目中出现了java中没有定义过的问题时,这时就需要我们按照java异常建立思想,将项目的中的特有问题也进行对象的封装。这个异常,称为自定义异常。

自定义异常的步骤:
1:定义一个子类继承Exception或RuntimeException,让该类具备可抛性。
2:通过throw 或者throws进行操作。

如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息传递给父类即可,通过super语句。
那么就可以直接通过getMessage方法获取自定义的异常信息。
代码示例:
class FuShuException extends Exception//自定义一个异常子类继承Exception类,该类用于建立异常对象
{
	private String msg;
	FuShuException(String msg)
	{
		super(msg);//super用于构造函数间的调用
	}
}
class Funtion
{
	private int a,b;
	public int Chu(int a,int b) throws FuShuException//声明异常
	{
		if (b<0)
		{
			throw new FuShuException("b不能是负数");//抛出异常对象
		}
		return a/b;
	}
}
class ExceptionDemo1 
{
	public static void main(String[] args) 
	{
		Funtion f = new Funtion();
		try
		{
			int x = f.Chu(5,-1);
			System.out.println("x="+x);
		}
		catch (FuShuException fu)//捕获到的具体的异常
		{
			System.out.println(fu.toString());
		}
		
	}
}

异常分为两种:
1,编译时异常,只要是Exception及其子类都是编译时被检测的异常。
2,运行时异常,其中Exception有一个特殊的子类RuntimeException,以及RuntimeException的子类是运行异常,也就说这个异常是编译时不被检查的异常。
编译时被检查的异常和运行时异常的区别:
编译被检查的异常在函数内被抛出,函数必须要声明,否则编译失败。
声明的原因:是需要调用者对该异常进行处理。
运行时异常如果在函数内被抛出,在函数上不需要声明。
不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理,直接让程序停止,由调用者对代码进行修正。

代码示例:
class FuShuException extends RuntimeException//继承了特殊的异常RuntimeException
{
	private String msg;
	FuShuException(String msg)
	{
		super(msg);
	}
}
class Funtion
{
	private int a,b;
	public int Chu(int a,int b) //RuntimeException是一个特殊的异常,编译时并不检测,这里无论是否声明异常,编译都能通过
	{
		if (b<0)
		{
			throw new FuShuException("b不能是负数");//抛出异常对象
		}
		return a/b;
	}
}
class ExceptionDemo2 
{
	public static void main(String[] args) 
	{
		Funtion f = new Funtion();
			int x = f.Chu(5,-1);//异常的语句同样不需要处理,因为当发生这种错误时,JVM将会停止程序运行,让调用者修正代码
			System.out.println("x="+x);
			System.out.println(f.toString());
	}
}

try...catch finally相结合时的三种格式
第一个格式:
try
{
}
catch ()
{
}
第二个格式:
try
{
}
catch ()
{
}
finally
{
}
第三个格式:
try
{
}
finally
{
}
注意:
catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明。
Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。
如果抛出的异常被处理了,就不用标示这个异常了

代码示例:
class Demo
{
	public void method()
	{
		//该异常已经被下列语句处理了,所以函数上不用标识异常,编译时也不会报错
		try
		{
			throw new Exception();
		}
		finally
		{
			//关资源。
		}
	}
}
class Demo
{
	public void method()
	{
		//此代码编译时会报错,因为函数上没有标识异常
		throw new Exception();
	}
}

覆盖时的异常特点:
异常在子父类覆盖中的体现
1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try catch处理。绝对不能抛。

个人理解:
覆盖时异常的特点分两大块
第一块:父类中抛出异常时,子类的覆盖方法,只能抛出父类中所抛出的异常的子集;
第二块:父类中没有抛出异常时,子类的覆盖方法,可以处理异常,但是不能抛出异常

异常的处理原则:
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();//转换的新的异常
		}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值