再谈Java

捕获异常
如果某个异常发生的时候没有在任何地方进行捕获,那程序就会终止,并在控制台上打印异常信息。其中包括异常的类型和堆栈的内容。对于图形界面,在捕获异常后也会打印堆栈信息,但程序将返回用户界面的处理循环中(在调试GUI程序时,最好保证控制台窗口可见,并且没有最小化)
要想捕获一个异常必须设置try/catch语句

try =
{
	code
	more code
	more code
}
catch(ExceptionType e)
{
	handler for this type
}

如果在try语句块中任何代码中抛出了一个在catch字句中说明的异常类,那么
1.程序将跳过try语句块其余的代码
2.程序将执行catch子句中的处理器代码
如果在try语句中没有抛出任何错误,那么将跳过catch代码块。如果在try中抛出了一个异常。没有想到合适的catch代码块,那么方法将直接退出。
有两种方式处理异常。
一种是try/catch语句在抛出异常时通过catch语句捕获异常
另外一种是直接抛出异常,将异常传递给调用者。
当选择这两种方法的时候,通常,应该捕获那些知道如何处理的异常,而那些不知道如何处理的异常将继续进行传递,如果想传递一个异常,就必须在方法的首部添加一个throws说明符。如果编写一个覆盖超类的方法,而这个方法又没有抛出异常,那么这个方法就必须捕获方法代码中每一个受查异常。不允许在子类的throws说明符中出现超过超类方法所列出的异常类范围
捕获多个异常
在一个try语句块中捕获多个异常类型,并对不同类型做出不同的处理。例如:

try
{
	code that might throw exception
}
catch(FileNotFoundException e)
{
	emergency action for missing files
}
catch(UnknowHostException e)
{
	emergency action for unknow hosts
}
catch(IOException e)
{
	emergency action forall other I/O problems
}

异常对象可能包含与异常类有关的信息,可以用e.getMessage()得到详细的
错误信息或者使用e.getClass().getName()得到异常对象的实际类型
在Java SE 7中,同一个catch子语句可以捕获多个异常类型,例如:

try
{
	code that might throw exception
}
catch(FileNotFoundException |UnknowHostException e)
{
	emergency action for missing files andunknow hosts
}
catch(IOException e)
{
	emergency action forall other I/O problems
}

捕获异常时,异常变量隐含为final变量
再次抛出异常与异常链
在catch子句中可以抛出一个异常,这样做的目的是改变异常类型,如果开发了一个供其他程序员使用的子系统,那么表示子系统故障的异常类可能会产生多种解释。

try
{
	access the	database
}
catch(SQLException e)
{
	throw new ServletException("database error"+e.getMessage);
}

将原始异常设置为新异常的“原因”

try
{
	access the database
}
catch(SQLException e)
{
	Throwble se = new ServletException("database error");
	se.initCause;
	throw se;
}

当捕获到异常时,可以使用下面这条语句重新得到原始异常:
Throwble e=se.getCause;
强烈建议使用这种包装技术。这样可以让用户抛出子系统中的高级异常,而不会丢失原始异常的细节。
编译器会查看catch块中的throw语句,然后查看e的类型,会指出这个方法可以抛出任何Exception而不是SQLException。现在这个问题有所改进。编译器会跟踪到e来自try块。
finally子句:
当代码抛出一个异常时,就会终止方法中剩余的代码的处理,并退出这个方法的执行。但是要想释放方法的本地资源,有一种方案比较乏味,捕获并重新抛出所有的异常,但是需要在两个地方清除资源:一个是正常的代码中,另外一个时异常代码中。
Java中有一种更好的解决方案,使用finally,不管是否发生异常,finally都会被执行。
例:

InputStream in = new FileInputStream(...);
try
{
	//1
	code that might throw exception
	//2
}
catch (IOException e)
{
	//3
	show error message
	//4
}
finally
{
	//5
	in.close
}
//6

在上面代码中,有下列三种情况将会执行finally。
1.代码没有抛出异常程序先执行try中全部代码,然后执行finally子句中的代码,随后执行try之后的第一条语句,执行1、2、5、6。
2.如果try语句抛出异常,那么就会终止执行try下的代码,再去执行catch,最后执行finally,如果catch没有抛出异常,那么就会执行try以后的第一条语句。
1、2、4、5、6。
3.代码抛出一个异常,但是catch没有捕获异常,也会执行finally,不会执行try语句的第一条语句,1、5.
try语句可以只有finally,而没有catch
finally也会返回return语句,但是假设在try语句中也存在return,也会执行finally,这样finally中的return返回的值会覆盖try中的值
有时候finally子句也会带来麻烦,清理资源的方法可能抛出异常。

InputStream in=...;
try
{
	code that might throw exceptions
}
finally
{
	in.close();
}

在try中可能抛出异常,但是在finally中也可能抛出try中相同类型的异常从而覆盖之前的异常。可以使用下列方法

InputStream in=...;
Exception ex=null;
try
{
	try{
		code that might throw exceptions
		}
	catch(Exception e)
	{
		ex=e;
		throw e;
	}
}
finally
{
	try
	{
		in.close();
	}
	catch(Exception e)
	{
		if(ex==null)throw e;
	}
}

带资源的try语句最简形式为

try(Resource res=...)
{
	work with res
}

javaSE 7为这种代码提供了void close() throws Exception try语句块退出时会自动调用res.close()。
可以调用getSuppressed方法,可以得到close方法抛出的异常。
带资源的try语句本身也可以有catch子句和一个finally子句,这些子句会在关闭资源之后执行。
分析堆栈轨迹
堆栈轨迹是一个方法调用过程的列表,它包含了程序执行过程中方法调用的特定位置,可以调用Throwable类的printStackTrace方法访问堆栈轨迹的文本描述信息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值