程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出java.lang.ArithmeticException的异常。
异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。
Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
java异常层次结构图:
总从图中可以看出所有异常类型都是内置类Throwable的子类,因而Throwable在异常类的层次结构的顶层。
接下来Throwable分成了两个不同的分支,一个分支是Error,它表示不希望被程序捕获或者是程序无法处理的错误。另一个分支是Exception,它表示用户程序可能捕捉的异常情况或者说是程序可以处理的异常。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常。
Java异常又可以分为非检查异常(Unchecked Exception)和检查异常(Checked Exception)。
下面将详细讲述这些异常之间的区别与联系:
Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
不受检查异常:包括RuntimeException及其子类和Error。
检查异常:在正确的程序运行过程中,很容易出现的、情理可容的异常状况,在一定程度上这种异常的发生是可以预测的,并且一旦发生该种异常,就必须采取某种方式进行处理。除了RuntimeException及其子类以外,其他的Exception类及其子类都属于检查异常,当程序中可能出现这类异常,要么使用try-catch语句进行捕获,要么用throws子句抛出,否则编译无法通过。
不受检查异常为编译器不要求强制处理的异常,检查异常则是编译器要求必须处置的异常。
Java的异常处理本质上是抛出异常和捕获异常
注意:对于运行时异常、错误和检查异常,Java技术所要求的异常处理方式有所不同。 对于方法运行中可能出现的Error,当运行方法不欲捕捉时,Java允许该方法不做任何抛出声明。因为,大多数Error异常属于永远不能被允许发生的状况,也属于合理的应用程序不该捕捉的异常。 由于运行时异常及其子类的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许应用程序忽略运行时异常。 对于所有的检查异常,Java规定:一个方法必须捕捉,或者声明抛出方法之外。也就是说,当一个方法选择不捕捉检查异常时,它必须声明将抛出异常。
java异常处理涉及到五个关键字,分别是:try、catch、finally、throw、throws。
*catch -- 用于捕获异常。catch用来捕获try语句块中发生的异常。在编写多个catch的时候,捕获范围大的异常一定要放在捕获范围小的异常后面。
throws 语法如下:
public void info() throws Exception { //body of method }
Exception 是该方法可能引发的所有的异常,也可以是异常列表,中间以逗号隔开。
Throws抛出异常的规则: * 如果是不受检查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。 * 必须声明可抛出的任何检查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误。 * 仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。 * 调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。
什么是断言?
就是肯定某一个操作的返回结果是正确的,如果程序执行到断言语句的时候,发现断言不正确了,返回结果是错误的了,则通过断言检查肯定,会为用户提示错误的信息。在jdk1.4引入了assert关键字。
断言的使用格式:
assert boolean 表达式; assert boolean 表达式:详细信息;
默认断言是不会影响程序正常运行的,在断言不成立时,也只会将信息显示出来。除非使用 java -ea 程序
手工启动断言。
虽然java已经提供了很多系统性异常,但在开发中还是无法满足实际的需要。所以java允许用户自定义异常。语法如下:
class 自定义异常类 extends 系统提供的异常类{ public 构造函数(String msg){ super(msg); //... } //... }
6.具体如果处理异常,要根据不同的业务需求和异常类型去决定。