Java的异常、断言、日志和调试

由于目前对于Java图形程序设计的暂时没有了解的计划,所以直接学习当前章节。

一、处理错误

( 1 )异常分类

在Java程序设计语言中,异常对象都是派生于Throwable类的一个实例,如果Java内置的异常类不能满足需求,用户可以创建自己的异常类。

如上图:所有的异常都继承自Throwable,但在下一层分解为两部分:Error和Exception。

1>Error类层次结构描述Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。如果出现这种内部错误,除了通告用户,并尽力使程序安全地终止之外,无能为力了。

2>Exception类层次结构又分为两个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。

i>划分规则:a>由程序错误导致的异常为RuntimeException。

b>程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常。

ii>派生于RuntimeException的异常包含:

a>错误的类型转换

b>数组访问越界

c>访问空指针

iii>不是派生于RuntimeException的异常包含:

a>试图在文件尾部后面读取数据。

b>试图打开一个不存在的文件。

c>试图根据给定的字符串查找Class对象,而这个字符串表示的类不存在。

注:  

a>如果出现RuntimeException异常,那么久一定是你的问题。

b>Java语言规范将派生于Error类或RuntimeException类的所有异常称为未检测异常。

    所有其他的异常称为已检查异常。

c>编译器将核查是否为所有的已检查异常提供了异常处理器。

( 2 )声明已检查异常

1>如果一个方法可能抛出多个已检查异常,那么就必须在方法的首部列出所有的异常类,每个异常类之间用逗号隔开。但是,不需要声明Java的内部错误,也不应该声明从RuntimeException继承的那些未检测异常。

总之,一个方法必须声明所有可能抛出的已检查异常,而未检查异常要么不可控制(Error),要么就应该避免发生。如果方法没有声明所有可能发生的已检查异常,编译器就会给出一个错误消息。

注:如果在子类中覆盖超类的一个方法,子类方法中声明的已检查异常不能比超类方法中声明的异常更通用。

( 3 )创建异常抛出

1>在出现异常时,先创建一个合适的异常类对象,并且抛出。

2>当已有的异常类不能很好解决问题时,可以自定义异常类。

(异常类派生于Exception类或派生于Exception子类的类)

二、捕获异常

通过try/catch语句块捕获异常。

如果调用一个抛出已检查异常的方法,就必须对它进行处理(try/catch),或者将它继续进行传递(throws)。

( 1 )捕获多个异常

( 2 )再次抛出异常与异常链

在catch子句中可以抛出一个异常,目的是改变异常的类型。

//第一种
try {
	access the database
} catch (Exception e) {
	throw new ServletException("database error:"+e.getMessage());
}
//第二种
try {
	
} catch (Exception e) {
	Throwable se = new ServletException("database error");
	se.initCause(e);
	throw se;
}
推荐使用第二种方式,因为它将原始异常设置为新异常的原因,当捕获异常时,可以通过Throwable e = se.getCause();获取原始异常。

( 3 )finally子句

不管是否有异常被捕获,finally子句中的代码都会被执行。

1>强烈建议独立使用try/catch和try/finally语句块,这样可以提高代码的清晰度。

这种设计不仅清楚,而且会报告finally子句中的错误。但是,当finally中也抛出异常时,原始的异常会丢失,转而抛出finally中的异常。

try {
	try {
		
	} finally{
			
	}
} catch (Exception e) {
	// TODO: handle exception
}

2>当try子句中存在return时,在方法返回前,finally子句的内容将执行。

    当finally子句中存在return时,这个返回值将会覆盖原始的返回值。

( 4 )带资源的try语句

如果资源属于一个实现了AutoCloseable接口的类,Java SE7为这种代码模式提供了一个很有用的快捷方式。AutoCloseable接口有一个方法。  void close() throws Exception

1>Closeable接口,属于AutoCloseable的子接口,也包含一个close方法,不过这个方法声明为抛出一个IOException

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

try块退出时,会自动调用res.close()。

2>使用带资源的try语句可以很好处理之前的情况,原来的异常会重新抛出,而close方法抛出的异常会“被抑制”。这些异常会将自动捕获,并由addSuppressed方法增加到原来的异常。

    使用getSuppressed方法,可以得到从close方法抛出并被抑制的异常列表。

注:带资源的try语句自身也可以有catch子句和一个finally子句,这些子句会在关闭资源之后执行,不过实际应用中一个try语句中加入这么多内容不是好主意。

( 5 )分析堆栈跟踪元素

堆栈跟踪(stack trace)是一个方法调用过程的列表,包含了程序执行过程中方法调用的特定位置。当Java程序正常终止,而没有捕获异常时,这个列表就会显示出来。

1>可以调用Throwable类的printStackTrace方法访问堆栈跟踪的文本描述信息。

2>使用getStackTrace方法,会得到StackTraceElement对象的一个数组,可以在你的程序中分析这个对象数组。

三、使用异常机制的技巧

使用异常机制的技巧

1>异常处理不能代替简单的测试。

2>不要过分地细化异常。

注:对于断言和日志的内容之后再详细学习。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值