关于Java中的异常处理:

关于Java中的异常处理:

常见的错误:

​ 1.用户输入错误

​ 2.设备错误

​ 3.物理限制

​ 4.代码错误

异常分类:

​ 在Java中,异常对象都是派生于Throwable类的一个实例。

在这里插入图片描述

Error:

​ 描述了Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。

Exception:

​ 可以分为两种,一种为RuntimeException:

​ 错误的类型转换;

​ 数组访问越界;

​ 访问null指针。

​ 非派生于RuntimeException的异常:

​ 试图在文件尾部后面读取数据;

​ 试图打开一个不存在的文件;

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

Java语言规范将派生于Error类或RuntimeException类的所有异常称为非受查(unchecked)异常,所有其他的异常称为受查(checked)异常。

什么时候该抛出异常呢?

1)调用一个抛出受查异常的方法。

2)程序运行过程中发现错误,并且利用throw语句抛出一个受查异常。

3)程序出现错误

4)Java虚拟机和运行时库出现的内部错误

一个方法必须声明所有可能抛出的受查异常,而非受查异常要么不可控制(Error),要么就应该避免发生(RuntimeException)。

如何抛出异常呢?

1)找到一个合适的异常类

2)创建这个类的一个对象

3)将对象抛出

捕获异常:

捕获异常,必须设置try/catch语句。

如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类,那么就有:

1)程序将跳过try语句块的其余代码

2)程序将执行catch子句中的处理器代码

如果在try语句块中没抛出任何异常,那么程序跳过catch子句。

如果方法中的任何代码抛出了一个在catch子句中没有声明的异常类型,那么这个方法就会立刻退出。

关于异常中的再次抛出:

try{

}
catch(SQLException e)
{
	throw new ServletException("databse error:" + e.getMessage());
}
//下面还有一种更好的处理方法,并且将原始异常设置为新异常的“原因”:
try{
	acess the database
}
catch(SQLException e)
{
	Throwable se = new ServletException("database error");
	se.initCause(e);
	throw se;
}
//当捕获到异常时,就可以使用下面这条语句重新得到异常:
Throwable e = se.getCause();
//这样可以让用户抛出子系统中的高级异常,而不会丢失原始异常的细节。

使用异常机制的技巧:

1.异常处理不能替代简单的测试,例如退栈之前,首先要查看栈是否为空。

if(!s.empty()) s.pop();
//下面是强行退栈后捕获EmptyStackException异常
try
{
	s.pop();
}
catch(EmptyStackException e){

}
//调用isEmpty只要646ms,捕获EmptyStackException时间需要21739ms,后者所需时间大大超过前者。

所以,只在异常情况下使用异常机制。

2.不要过分地细化异常

有必要将整个任务包装在一个try语句块中,这样,当任何一个操作出现问题时,整个任务都可以取消。

//对比一下
PrintStream out;
Stack s;
for(i = 0; i < 100; i++)
{
	try
	{
		n = s.pop();
	}
	catch(EmptyStackException e)
	{
		//stack was empty
	}
	try
	{
		out.writeInt(n);
	}
	catch(IOException e)
	{
		//problem writing to file
	}
}
//上面这种方式会使代码量急剧膨胀

try
{
	for(i = 0; i < 100; i++)
	{
		n = s.pop();
		out.writeInt(n);
	}
}
catch(IOException e)
{
//problem writing to file
}
catch(EmptyStackException e)
{
//stack was empty
}

下面的方法就使代码更清晰。

3.利用异常层次结构。

不要只抛出RuntimeException异常。应该寻找更加适当的子类或创建自己的异常类。

不要只捕获Throwable异常,否则,会使程序代码更难度、更难维护。

将一种异常转换成另一种更加适合的异常时不要犹豫。比如,在解析某个文件中的一个整数时,捕获NumberFormatException异常,然后将它转换成IOException或MySubsystemException的子类。

4.不要压制异常。

5.在检测错误时,"苛刻"比放任好

检测到错误时,不要担心抛出异常。例如无效的参数调用一个方法时,返回一个虚拟的数值,还是抛出一个异常。比如,栈空时,是返回一个null,还是抛出一个异常?我们认为:在出错的地方抛出一个EmptyStackException的异常要比在后面抛出一个NullPointerException异常更好。

6.不要羞于传递异常

例如,FileInputStream构造器或readLine方法,这些方法就会本能地捕获这些可能产生的异常。其实,传递异常要优于捕获这些异常

让高层次的方法通知用户发生了错误,或者放弃不成功的命令更加适宜。

错的地方抛出一个EmptyStackException的异常要比在后面抛出一个NullPointerException异常更好。

6.不要羞于传递异常

例如,FileInputStream构造器或readLine方法,这些方法就会本能地捕获这些可能产生的异常。其实,传递异常要优于捕获这些异常

让高层次的方法通知用户发生了错误,或者放弃不成功的命令更加适宜。

5、6归结为“早抛出,晚捕获”。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值