异常处理

Java的异常处理主要依赖try,catch,finally,throw,和throws五个关键字,finally块用于回收在try块里打开的物理资源,异常机制保证finally块总被执行。throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常(不确定的);throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的一场对象。    

<span style="font-size:14px;">try{
//业务实现代码
    ...
}
catch(Exception e)
{
    alert 输入不合法
    goto retry
}</span>

如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,该异常对象被提交给Java运行时环境,这个过程被称为抛出(throw)异常。当java运行时环境收到异常对象时,会寻找能处理该一场对象的catch块,如果找到合适的catch块,则把该异常对象交给该catch块处理,这个过程被称为捕获(catch)异常,如果java运行时环境找不到捕获异常的catch块,则运行时环境终止,java程序也将退出。


    当Java运行时环境接收到异常对象时,如何为该异常对象寻找catch块呢?catch关键字的形式:(Exception e )这意味着每个catch块都是专门用于处理该异常类及其子类的异常实例。当java运行时环境接收到异常对象后,会依次判断该异常对象是否是catch块后异常类或其子类的实例,如果是,Java运行时环境将调用该catch块来处理该异常;否则再次拿该异常对象和下一个catch块里的异常类进行比较。

    注意:try块与if语句不一样,其后的{...}不可省略,即使只有一行代码,catch块与之相同。try块里声明的变量时代码块内部的局部变量,它只在try块内有效,在catch块中不能访问该变量。进行异常捕获时要把Exception类对应的catch块放在最后,而且所有的父类异常的catch块都应该排在子类异常catch块的后面(简称:先处理小异常,再处理大异常),否则编译错误。

    catch块捕获多种异常:

<span style="font-family:Microsoft YaHei;font-size:14px;">public class DivTest {
    try 
    {
    	int a = Integer.parseInt(args[0]);
    	int b = Integer.parseInt(args[1]);
    	int c = a/b;
    	System.out.println("您输入的两个数相除的结果是:"+ c);
    }
    catch(IndexOutOfBoundsException|NumberFormatException|ArithmeticException ie)
    {
    	System.out.println("程序发生了数组越界、数字格式异常、算数异常之一");
    	//捕获多异常时,异常变量默认有final修饰
    	//所以下面代码有误
    	ie = new ArithmeticException("test");
    }
    catch(Exception e)
    {
    	System.out.println("未知异常");
    	//捕获一种类型的异常时,异常变量没有final修饰
    	//下面代码正确
    	e = new RuntimeException("test");
    }
}</span>

  • 捕获多种类型的异常时,多种异常类型之间用竖线(|)隔开
  • 捕获多种类型的异常时,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值。
    Java的垃圾回收机制不会回收任何物理资源(例如数据库连接,网络连接和磁盘文件等),垃圾回收机制只能回收内存中的对象所占用的内存。
使用finally回收资源
      try块中打开的物理资源必须显示回收。
      除非在try块、catch块中调用了退出虚拟机的方法(//System.exit(1);)否则不管在try块、catch块中执行怎样的代码,出现怎样的情况,异常处理的finally块总会被执行。在通常情况下,不要再finally块中使用如return或throw等导致方法终止的语句。一旦在finally块中使用了return或throw语句,将会导致try块、catch块中的return、throw语句失效。
Java7的自动关闭资源的try语句
      java7增强了try语句的功能,在try关键字后紧跟一对圆括号,圆括号可以声明、初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源,try语句在该语句结束时自动关闭这些资源。这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口必须实现close()方法。
<span style="font-family:Microsoft YaHei;font-size:14px;">public class AutoCloseTest {

	public static void main(String[] args)
	throws IOException
	{
		try(
				//声明、初始化两个可关闭的资源
				//try语句会自动关闭着两个资源)
				BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));
				PrintStream ps = new PrintStream(new FileOutputStream("a.txt")))
	    {
		         //使用两个资源
			System.out.println(br.readLine());
			ps.println("庄生晓梦迷蝴蝶");
	    }
	}
}</span>

    Java7几乎把所有的“资源类”(包括文件IO的各种类、JDBC编程的Connection、Statement等接口……)进行了改写,最后资源实现类都实现了AutoCloseable或Closeable接口。
     throws声明抛出只能在方法签名中使用。一旦使用throws语句声明抛出该异常,程序无需使用try…catch块来捕获该异常。
<span style="font-family:Microsoft YaHei;font-size:14px;">public class ThrowsTest {

	public static void main(String[] args)
	throws IOException
	{
		FileInputStream fis = new FileInputStream("a.txt");
	}
}</span>
    上面程序声明不处理IOException异常,将该异常交给JVM处理,程序一旦遇到该异常,JVM就会打印该异常的跟踪栈信息,并结束服务。

catch和throw同时使用
(在大型企业级应用中非常常用1、应用后台需要通过日志来记录发生的详细情况;2、应用还需要根据异常向应用使用者传达某种提示。在这种情况下,所有异常都需要两个方法共同完成,也就必须将catch和throw结合使用)
前面介绍的异常处理方式:
  1.  在出现异常的方法内捕获并处理异常,该方法的调用者将不能再次捕获该异常。
  2.  在方法签名中声明抛出该异常,将该异常完全交给方法调用者处理。
     在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次抛出异常,让该方法的调用者也能捕获到异常。
   为了实现这种通过多个方法协同处理同一个异常,可以在catch块中结合throw语句来完成。
<span style="font-family:Microsoft YaHei;font-size:14px;">public class AuctionTest {
	private double initPrice = 30.0;
	//因为该方法中显示抛出了AuctionException异常
	//所以在此处需要显示声明抛出AuctionException异常
	public void bid(String bidPrice)
	throws AuctionException
	{
		double d = 0.0;
		try
		{
			d = Double.parseDouble(bidPrice);
		}
		catch(Exception e)
		{
			//此处完成本方法中可以对异常执行的修复处理
			//此处仅仅是在控制台打印异常的跟踪栈信息
			e.printStackTrace();
			//再次抛出自定义异常
			throw new AuctionException("竞拍价必须是数值," + "不能包含其他字符");
		}
		if(initPrice > d)
		{
			throw new AutionException("竞拍价比起拍价低" + "不允许竞拍");
			initPrice = d;
		}
		public static void main(String[] args)
		{
			AuctionTest at = new AuctionTest();
			try
			{
				at.bid("df");
			}
			catch(AuctionException ae)
			{
				//再次捕获到bid()方法中的异常,并对该异常进行处理
				System.err.println(ae.getMessage());
			}
		}
	}

}
</span>



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值