- 异常的概念
异常简单来讲,就是程序在运行时出现的特殊情况。在现实生活中,问题也是其具体的一个事物。那么在java中,就有相对应对问题的描述的类,并对该类进行封装成对象。这种对问题的封装,就叫做异常。异常是一种对象,他从出错地点被“抛出”,并被异常处理器(专门设计用来处理相应错误)“捕获”。异常处理器就像是与程序正常执行路径并行的,在错误发生时执行的另一条路径。总得来说,异常提供了一种从错误状况进行可靠恢复的途径。
- 异常的描述
在现实生活中,可以对问题进行两种划分,一种严重的问题(比如癌症晚期)和非严重的问题(感冒)
针对这种划分,java也分别进行了两种描述。
1.对于严重的问题,java通过Error类描述。由于其严重性,一般不编写针对性代码进行处理
2.对于非严重的问题,java通过Exception类。与上面相反。
- 异常的继承情况-Throwable
无论是Error还是Exception都是对问题的描述,因此他们也具有一些相同的地方。比如都属于程序运行时的不正常情况,都具有引发的原因,此时就有一个类对该共性进行向上抽取,该类为Throwable,他是所有错误或者异常的父类
- 异常的处理
针对异常处理,java提供了一种特有的语句进行处理
try{需要被检测的代码
}
catch(异常类 变量){异常代码的处理方式
}
finally{一定会执行的语句
}
一旦try代码块中有语句产生异常,java就会生成该异常情况的对象,并跳出try(之后的语句不会执行),将该对象传递给catch方法的形参,进行处理(没有问题catch不运行)
- catch到的异常对象有哪些操作?
PS:当然你可以在里面写任何语句,下面是针对异常对象的描写
首先在catch(异常类 变量)括号里的形参为 比如:Exception e,为所有异常类的父类,因此所有异常情况的对象都可以传递给该引用变量(多态),也可以为更具体的异常类(这是常见的写法),比如:ArithmeticException e
操作如 getMessage();printStackTrace();等等,查一下API就知道了
这里要提一下,JVM默认执行的方法就是printStackTrace();
- throws Exception
大家都知道程序分为开发者和使用者,但是使用者在使用开发者设计的程序时,并不知道该程序会有可能出现异常,那么也就不会或者说没有理由去使用try-catch去捕获。这时就需要开发者使用Throw Exception语句来声明,告诉使用者这个方法是有可能发生错误的,语法如下
public void show() throws xxx1Exception,xxx2Excepetion
{语句1
语句2……}
而这个声明强制使用者在使用该方法时必须使用try-catch去捕获这个异常或者继续声明抛出异常,不然程序无法执行。也就是说,使用者也可以通过throws关键字来抛出这个异常,这样他便可以不捕获异常也能正常运行程序。异常可以一直抛,直到最终抛到JVM,也就是java虚拟机为止,虚拟机就会默认执行我上面说的printStackTrace();方法执行,所以一般不这样操作。
- 多异常的处理
1.程序发生的异常有时不止一个,因此在声明问题时(throws Exception),问题的个数也不止一个。需要注意的是,在声明问题时,建议进行具体的声明,这样throws Exception简单粗暴的方法是不好的,因为使用者根本不知道会发生具体哪些问题,不能针对性的catch。只有开发者声明的具体,那么使用者才会处理的更具体
2.程序throws几个异常就catch几个异常,即使你认为程序可以发生其他异常,也不能没意义的写 catch(Exception e)这个代码,因为这个解决不了问题,你应该做的是当发生其他额外的异常时进行修正代码,或者抛出新的异常去捕获。
3.如果catch块中出现继承关系,应该把父类放在下面,不然子类catch块就没有存在的意义。(子类问题被父类给catch了,多态)
- 自定义异常
1.异常作为类,他就可以被封装成各种对象。在编写程序的过程中会发生各种各样针对性的异常,而这些异常有可能java库里没有,所以对于特有的问题,我们将自己对问题进行封装,自定义异常。
QQ截图20151210144426.png2.但是他必须继承自Throwable,如下
class yichang extends Exception{}
为什么呢,因为只有Throwable类才具有抛和catch的特性
异常类是有信息的,他是可以通过to String()方法调用的
- throw&throws
这里讲一下throw和throws的区别
1.throws写在函数上 throw写在函数内
2.throws后面跟的是异常类,可以是多个,用逗号隔开
throw后面跟的是异常对象,并且需要注意的是,throw和return一样,一旦抛出异常,那throw后面的语句都不会执行,因此他们都是结束标识。
- RuntimeException
这里需要提到一个特殊的异常,运行时异常——RuntimeException
**1.如果在函数内抛出该异常,那么该异常不用被声明
2.同样的,如果该异常被声明,在使用时不需要处理(抛或者捕获)
**
为什么会有这么一个特殊的异常呢,因为该异常说明的问题一旦发生,那么之后的程序都无法运行,所以开发者有必要让使用者知道该问题,否则的话该问题就会被隐藏起来(通过抛或者catch来规避该问题)。
所以当你自定义异常,希望该异常发生时无法再继续,那么就需要自定义的异常继承RuntimeException.
举个例子,比如晚上你要看书,可是书房的灯泡坏了,这个时候你可以去其他灯泡好的房间继续看书;可是如果家里停电了呢,你就必须要处理好停电的问题才能继续看书,这就是RuntimeException,当然你也可以凿壁借光。。。
- 继承关系中的异常
一句话,子类不能抛出父类没有抛出过的异常!
网友评论