异常

一、  Java中的Throwable体系

Throwable
	Error
	Exception
		Checked异常(没有这种异常名,只是一种范畴)
			IOException
			… …
		RuntimeException
			IndexOutOfBoundException
			NullPointException
			ClassCastException
			ArithmeticException
			IllegalArgumentException
			… …

Java把非正常的情况分为两种:Error(错误)和Exception(异常),它们都继承Throwable父类。

         Error:一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接错误等,这种错误无法恢复或者不可捕获,将导致应用程序终端。通常应用程序无法处理这种错误,所以无须使用catch块捕获Error对象,定义方法时也无须用Throws声明可能抛出Error或者其子类。

         Exception:就是程序在运行时出现的不正确情况。通过Java类的形式对这种情况进行描述后封装成对象,这种封装了问题的对象及时异常。

二、  异常处理机制的优点

         1)、让程序具有极好的容错性,让程序更加健壮。

         2)、程序运行出现意外情形时,系统自动生成Exception对象,实现“错误处理代码”和“业务功能实现代码”分离,提高代码的可读性。

三、  Exception异常划分

         Checked异常:是指编译时被检测异常。Java认为Checked异常都是可以在编译阶段处理的异常,所以它强制程序处理所有的Checked异常。Checked异常可以提醒程序员需要处理有可能发生的异常。

         Runtime异常:是指运行时异常。在编译时编译器不检测,也不需要处理,当异常发生后程序停止,需要对代码进行修正。不过也可以对其进行try,catch,但是这样做很可能把问题隐藏起来,程序代码的错误(bug)被掩盖在运行当中无法被察觉。

四、  异常处理格式

try
{
	需要被检测的代码;
}
catch(需要捕获的异常类型 引用变量)
{
	处理异常的代码;
}
catch()
{
	
}
...
finally
{
	一定会执行的代码;(通常用于关闭资源)
}
注意:finally只有一种情况不会执行到,就是在finally之前,出现了System.exit(0);该方法的执行作用是系统退出,JVM结束。

五、  throws和throw的区别

         throws用在函数上,后面跟异常类,可以跟多个,用逗号隔开

         throw用在函数内,后面跟的是异常对象。

六、  异常处理代码演示

//自定义一个继承Exception的异常
class CheckedException extends Exception
{
	CheckedException(){}
	CheckedException(String message)
	{
		super(message);
	}
}
class Demo
{
	public void method1()throws CheckedException//抛出异常
	{
		System.out.println("我在使用的时候可能出现问题");
	}
	public void method2(String str)
	{
		if(str == null)
			throw new NullPointerException("你没有传入参数");
			//抛出的是NullPointerException异常对象,该异常是RuntimeException的子类。
			//throw new CheckedException("你没有传入参数");
			//CheckedException不是RuntimeException的子类,所以必须在方法定义时声明,否则编译失败。
	}
	public void method3()throws CheckedException//抛出异常
	{
		method1();//调用声明了异常的方法,没有处理,就继续向外抛。
	}
}
class ExceptionDemo
{
	public static void main(String[] args)//throws Exception
	{
		Demo d = new Demo();
		/*如果调用声明异常的方法时,没有try,那么需要将异常继续向外抛(在外层方法声明异常),
		如果都没有处理,最终必须要在主函数处声明抛出,此时由虚拟机的异常处理机制处理,否则编译失败。
		d.method1();
		d.method3(); 
		*/
		try
		{
			d.method1();
			d.method3();		
		}
		catch(Exception e)
		{
			
		}
		d.method2(null);//运行时抛出RuntimeException的子类异常——NullPointerException
		System.out.println("该程序发生RuntimeException,我不在执行");
	}
}
由代码可见:method1和method2声明了Checked异常(编译时异常),说明这两个方法在使用的时候可能出现问题,那么在调用该方法的时候有两种处理方式:

         1)、用try、catch处理。就是把有可能出现问题的代码放进try代码块,把处理信息放在catch代码块。(这只是一种未雨绸缪的做法,有问题时catch才会执行,没问题时catch不执行)

         2)、继续向外抛。就是在外层方法声明该异常,提醒调用的人处理。如果调用的人还是没有处理,可以继续抛。可能最终在主函数处抛出,那就由虚拟机的异常处理机制打印出堆栈内存中的跟踪信息。

由代码可见,如果method2方法内抛出一个Checked异常对象,必须在方法定义出申明异常。但是method3方法内部抛出了一个RuntimeException的子异常对象,所以方法不需要声明异常,也不必要放在try代码块内,让它运行时候直接报错,程序停止。你就会知道是自己在使用方法时出错,从而修改代码。也可以把method3方法放在try代码块中,不过错误可能被隐藏。

七、  使用异常时的注意事项:

1、方法重写时,异常的抛出特点:

        1)、重写方法声明抛出的异常应该是被重写方法声明抛出异常类型的子类或者相同,

        2)、重写方法抛出的异常不允许比被重写方法声明抛出的异常多。

        3)、当被重写方法没有抛出异常,而重写方法出现了异常,这时只能try,catch处理,不能抛。

2、因为一旦捕获到异常,程序将停止。所以当try中可能有多个异常,进行catch捕获时,一定要先捕获小异常,再捕获大异常。所以不仅要把Exception对应的catch块放在最后面,而且所有父类异常的catch块必须放在子类异常catch块的下边。

八、  自定义异常:

         因为异常类名通常包含了该异常的有用信息。所以在选择抛出异常时,应该选择合适的异常类,从而可以明确的描述该异常的情况。所以需要抛出自定义异常。

         自定义异常必须继承Exception基类,如果希望自定义Runtime异常,则必须继承RuntimeException基类。

         自定义异常通常需要提供两个构造器:一个是无参数的构造器;另一个是是带有一个字符串参数的构造器,这个字符串作为该异常对象的描述信息,也就是异常对象getMessage()方法返回值。

为避免误导初学者,本博客如有错误或者不严谨的地方,请在下方给予评论,以便及时修改!谢谢... ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值