所谓异常就是程序在运行时出现的不正常情况在java中万物皆对象,所以问题也可以通过类的形式来描述,并封装成对象。
所有异常类的超父类是Throwable,他有两个子类对象,一个是Error,一个是Exception。Throwable中定义了相应构造函数,和诸如
getMessage()à获取异常信息、
printStackTrace()à得到详细信息、
toString()à获取异常信息与类型等方法用来给子类继承。
异常分为两种:1、编译时被检测的异常。
2、编译时不被检测的异常,又称运行异常,是由RuntimeException及其子类构成。
对异常的处理上java提供了特有的代码格式,如下:
try
{(这里写需要被检测的代码)
}
catch(异常类 变量)------à(exception e)
{(这里写对异常的处理方法)
}
Fnally
{(一定会被执行的语句)
}
在定义函数的时候,如果发现会有可能出现异常,需要在函数后面用throws Exption声明。对于调用该函数的方法,必须对该函数的异常进行处理,或者同样抛出给其调用者。否则编译失败。
在这里我们可以用老师上课用电脑的例子来理解异常的抛出。老师上课用电脑,电脑突然死机了,这个时候我们自己能解决,只需要重启一下就好了,所以把这个异常在老师自己的方法内就可以try和catch。但是如果机器突然爆炸了,这个老师自己处理不了,必须要把这个异常反馈给调用老师的对象方法学校,这个时候就需要将机器爆炸这个异常进行抛出。
在对多异常进行声明的时候,最好能将异常声明的更具体一些,这样在调用的时候可以根据相应异常信息进行具体的处理,比较常见的异常有
NullpointException-->空指针异常
ArrayIndexException-->数组角标越界异常
RuntimeException-->运行时异常
函数声明了几个异常,调用者就写几个catch,如果多个catch出现继承关系,那么父类的catch向下放。因为父类catch块放在上面的话,根据Java对象多态的原则,即使出现了子类异常,也会先catch到父类,所以子类的catch会永远执行不到,就成了废代码,编译时就会报错。
自定义异常,是为了来描述一些java未描述的异常。将这些异常按照java类的封装思想,将他们自定义成一个异常类。他必须是Exception或者Error的子类。
比如一个除法的方法,他的除数不能为零,他在编译的时候JDK是无法处理的很好也不会报错,这时我们就需要自己定义一个异常来告诉程序的调用者。自定义异常的名字应该增加阅读性应该是前缀名为具有意义能描述异常的单词后缀为Exption父类名。如果我们希望这个异常发生时程序不再继续向下执行,则继承RuntimeException。因为RuntimeException是一个特殊的子类异常类,在函数内容出现了该异常,函数可以不用声明,即使声明了,调用者不对其进行处理也没有继续抛出,一样可以通过编译。原因是,当发生该类异常代表无法继续运算,所以希望程序停止,来对代码进行修正。当要定义自定义异常的异常信息时,可以使用父类已经定义好的功能。将异常信息传递给父类的构造函数。如下:
class MyException extends Exception
{
MyException(String message)
{
Super(message);
}
}
然后我们就可以再函数内对我们自定义的这个MyException异常进行抛出,比如定义一个是否要抛出的满足条件
if(x>1)
{
throw new MyException("自定义异常");
}
这样如果x大于1的话,在控制台上就会显示出
对于实际开发时我们同样可以通过io技术将异常捕获之后和当前时间一起写入异常日志,以文档的形式存储起来,方便程序设计者阅读,从而更改程序代码的不足。
在函数中抛出自定义的异常,需要用关键字throw来描述。只要函数内出现异常,除了RuntimeException的子类异常,函数上需要声明。
throws和throw的区别。
1、 thorows是在函数上;而throw是在函数内。
2、 throws后面是跟着异常类,可以跟多个,用逗号隔开;而throw后面跟的是异常对象。
finally代码块是用来定义一定要执行的代码。通常用来关闭资源。例如IO流对象,UDP,TCP传输时的流对象。如一个方法需要连接数据库进行操作,操作过程中无论遇没遇到异常,都一定要把数据库断开连接,来释放资源。只有一种情况下执行不到,那就是之前执行了System.exit(0)命令,也就是结束jvm的命令。
异常在子父类覆盖的时候。如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。如果父类抛出多个异常,那么子类在覆盖方法的时候,只能抛出父类异常的子集。如果父类没有异常抛出,那么子类也不可以有异常抛出。如果方法真的有异常发生,那么就在函数内进行try处理。
异常在阅读性上的优势是可以将异常封装,将正常的流程代码和问题处理代码分离,这样看起来一目了然,方便阅读。