Java常见异常处理

Exception类:

在java中用类的形式对不正常情况进行了描述和封装对象,异常就是java通过面向对象的思想将问题封装成了对象。


异常发生的原因有很多,通常包含以下几大类:

  • 用户输入了非法数据
  • 要打开的文件不存在
  • 网络通信时连接中断
  • JVM内存溢出

Throwable:

Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。

  //该体系的特点就在于Throwable及其所有的子类都具有可抛性。

可抛性到底指的是什么呢?怎么体现可抛性呢?

   是通过两个关键字来体现的。

    throws和throw ,凡是可以被这两个关键字所操作的类和对象都具备可抛性。


  |--1,一般不可处理的:Error
    特点:是由jvm抛出的严重性的问题。这种问题发生一般不针对性处理,直接修改程序。

  |--2,可以处理的:Exception


 异常的分类:

1,编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。这样的问题都可以针对性的处理


2,编译时不检测异常(运行时异常,比较多见):就是Exception中的RuntimeException和其子类。
这种问题的发生无法让功能继续,运算无法进行,更多是因为调用者的原因导致的或者引发了内部状态的改变导致的。
那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。

 

自定义异常:

有的异常在Java中并没有定义过,可以按照java异常的创建思想,面向对象,将异常进行自定义描述。并封装成对象。声明异常的目的是让调用者来处理这些问题。

自定义异常时,要么继承Exception。要么继承RuntimeException。

*继承Exception需要throws来声明,继承RuntimeException不需要。*

 

throws 和throw的区别:

1,throws使用在函数上,throw使用在函数内。
2,throws抛出的是异常类,可以抛出多个,用逗号隔开。throw抛出的是异常对象


异常处理的捕捉形式:(常用)

这是可以对异常进行针对性处理的方式。

具体格式是:

try
{
    //需要被检测异常的代码。
}
catch(异常类 变量)//该变量用于接收发生的异常对象
{
    //处理异常的代码。
}
finally
{
    //一定会被执行的代码。
}

 

异常处理的原则:
1,函数内容如果抛出需要检测的异常,那么函数上必须要声明。
否则必须在函数内用trycatch捕捉,否则编译失败。
2,如果调用到了声明异常的函数,要么trycatch要么throws,否则编译失败。
3,什么时候catch,什么时候throws?
功能内容可以解决,用catch。
解决不了,用throws告诉调用者,由调用者解决 。
4,一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。
内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。

例:

class FuShuIndexException extends Exception//*自定义异常*:输入的数组角标为负*
{
    FuShuIndexException()
    {}
FuShuIndexException(String msg) {
super(msg); } } class Demo { public int method(int[] arr,int index)throws NullPointerException,FuShuIndexException { if(arr==null) throw new NullPointerException("没有任何数组实体"); if(index<0) throw new FuShuIndexException("数组角标不能为负"); return arr[index]; } } class ExceptionDemo4 { public static void main(String[] args) { int[] arr = new int[3]; Demo d = new Demo(); try { int num = d.method(arr,-1); System.out.println("num="+num); } catch(NullPointerException e) { System.out.println(e.toString()); } catch (FuShuIndexException e) { System.out.println("message:"+e.getMessage()+"\n"); System.out.println("string:"+e.toString()+"\n");//对象变成字符串打印(一般是哈希值) e.printStackTrace();//jvm默认的异常处理机制就是调用异常对象的这个方法。 } /* catch(Exception e)//多catch,父类的catch放在最下面。(面试) { } */ System.out.println("over"); } }

运行结果:

message:数组角标不能为负

string:FuShuIndexException: 数组角标不能为负

FuShuIndexException: 数组角标不能为负
over
	at Demo.method(TestException.java:22)
	at ExceptionDemo4.main(TestException.java:35)

Finally代码块:

在异常出现后仍会运行的代码块,通常用于用于关闭(释放)资源。

 

几种代码组合形式:

1,
try catch finally

***例:*** 异常转换(封装)

void addData(Data d)throws NoAddException
{

	连接数据库
	try
	{
	        添加数据。出现异常 SQLException();
	}
	catch(SQLException e)
	{
		//处理代码。
		throw new NoAddException();//***处理不了的问题要继续抛出***,告诉调用者添加数据没有成功。
	}
	fianlly
	{
	      //关闭数据库。
	}
}

2,

try catch(多个)当没有必要资源需要释放时,可以不用定义finally。
3,
try finally 异常无法直接catch处理,但是资源需要关闭。

例:

void show()throws Exception
{
	try
	{
		//开启资源。
		throw new Exception();
	}
	finally
	{
		//关闭资源。	
	}	
}

子父类异常的注意事项:

1,子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。

2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集。

 简单说:子类覆盖父类只能抛出父类的异常or子类or子集。

注意:如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try .

  

posted @ 2017-03-12 17:13  Kkky  阅读(310)  评论(0编辑  收藏  举报