异常
什么是异常
Java代码咋运行时期发生的问题就是异常- 在Java中,把异常信息封装成了一个类,当出现问题时,就会在创建异常类对象并抛出异常的相关的信息(如异常出现的位置,原因等等)
异常体系
- 在
Java中使用Exception类来描述异常

- 查看API 中
Exception类以及其子类是Throwable,的一种形式,它用来表示Java程序中可能会产生的异常,并要求对生产的异常进行合理的异常处理; - 继续观察,我们可以发现
Exception有继承关系,它的父类是Throwable, Throwable是Java语言中所有错误或异常的超类,即祖宗类 
- 另外,在异常Exception类中,有一个子类要特殊说明一下:
RuntimeException子类,RuntimeException及其他的子类只能在Java程序运行过程中出现
- 观察
Throwable类,能够发现与异常Exception平级的有一个Erro,它是Throwable的子类,它用来表示Java程序中可能会产生的严重错误,解决办法只有一个,修改代码避免Erro错误的产生 
- 异常继承体系总结
Throwable : 它是所有错误与异常的超类(祖宗类)
| - Error : 错误
| - Exception : 编译器异常,进行编译Java程序时出现的异常(问题)
| - RuntimeException : 运行期异常,Java程序运行过程中出现的问题
异常与错误的区别
异常
- 指程序在编译,运行期间发生了某种异常(XxxException),我们可以对异常进行具体的处理,若不处理异常,程序会结束运行.
- 异常的产生演示如下:
public static void main(String[] args) {
int[] arr= new int[3];
System.out.println(arr[0]);
System.out.println(arr[3]);
System.out.println("over");
}
错误
- 指程序在运行期间发生了某种错误(XxxError),
Error错误通常没有具体的处理方式,程序将会接受运行,Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的,我们无法针对处理,只能修正代码. - 错误的产生如下
int[] arr= new int[1024*1024*1024]
异常解析过程
- 运行下面的程序,程序会发生一个数组索引越界异常
ArrayIndexOutOfBoundsException.我们通过图解来解析下异常产生的过程 - 工具类
public class ArrayTools{
public static int getElement(int[] arr,int index) {
int element = arr[index];
return element;
}
}
public class ExceptionDemo2 {
public static void main(String[] args) {
int[] arr = {34,12,67};
int num = ArrayTools.getElement(arr,4)
System.out.println("num="+num);
System.out.println("over");
}
}
- 上述程序执行过程图解

捕获异常try...catch...finally
- 捕获 : Java中对异常针对性的语句进行捕获,可以对出现的异常进行指定方式的处理
- 捕获异常格式
try{
}catch(异常类 变量){
}finally{
}
try : 该代码块中编写可能发生异常的代码catch : 用来进行某种异常的捕获,实现对捕获到的异常进行处理finally: 有一些特定的代码无论是否发生异常,都需要执行,另外,因为程序发生异常会引发程序跳转,导致有些语句执行不到,而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的
public class ExceptionDemo {
public static void main(String[] args) {
try {
int[] arr = new int[3];
System.out.println(arr[5]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("异常发生了");
}finally {
int[] arr = null;
}
System.out.println("程序运行结束");
}
}
try...catch...finally异常处理的组合方式
try catch finally组合 : 检测异常,并传递给catch处理,并在finally中进行资源释放.try...catch组合 : 对代码进行异常检测,并对检测出的异常传递给catch处理,对异常进行捕获处理
void show(){
try{
throw new Exception();
}catch(Exception e){
}
}
- 一个
try多个catch组合 : 对代码进行异常检测,并对检测的异常传递给catch处理,对每种异常信息进行不同的捕获处理
void show(){
try{
throw new Exception();
}catch(XxxException e){
}catch(XxxException e){
}catch(XxxException e){
}
}
- 注意 : 这种异常处理方式,要求多个
catch中的异常不能相同,而且若catch中多个异常之间存在子父类关系,那么子类异常要求在上面catch处理,父类异常要求在下面的catch处理 try... finally组合 : 对代码进行异常检测,检测到异常后因为没有catch处理,所以一样会被默认jvm抛出,异常是没有捕获处理的,但是功能所开启的资源需要关闭,所以finally,只为关闭资源
void show(){
try{
throws new Exception
}finally{
}
}
抛出异常 : throw(关键字)
- 在编写程序时,我们必须要考虑程序出现问题的情况,比如,在定义方法时,方法需要接受参数,那么调用方法使用接受到的参数时,首先需要判断参数数据是否合法,如果数据不合法,就应该告诉调用者,传递合法的数据进来,这时需要使用抛出异常的方式告诉调用者.
- 在Java中,提供了一个
throw关键字,它用来抛出一个指定的异常对象,
那么抛出一个异常具体如何操作呢?
- 创建一个异常对象,封装一些提示信息(信息可以自己编写)
- 需要将这个异常对象告知调用者,怎么告知?怎么将这个异常对象传递到调用者处呢? 就是通过关键字throw就可以完成.throw异常对象. - 使用格式
throw new 异常类名(参数);
throw new NullPointerException("要访问的arr数组不存在");
throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围")
public class ArrayTools{
public static int getElement(int[] arr,int index) {
if(arr==null){
throw new NullPointerException("arr指向的数组不存在");
}
if(index<0 || index>=arr.length){
throw new ArrayIndexOutOfBoundsException("错误的角标,"+index+"索引在数组中不存在");
}
int element = arr[index];
return element;
}
}
public class ExceptionDemo3 {
public static void main(String[] args) {
int[] arr = {34,12,67};
int num = ArrayTools.getElement(null,2);
System.out.println("num="+num);
}
}
声明异常 : throws
- 声明 : 将问题标识出来,报告给调用者.如果方法内通过
throw抛出了编译时异常,而没有捕获处理,那么必须童工throws进行声明,让调用者去处理 - 声明异常格式
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2...{
}
public class throws1 {
public static int show(int x) throws Exception{
if (x>0){
throw new Exception();
}else{
System.out.println("show run");
}
return 0;
}
}
throws 用于进行异常类的声明,若该方法可能有多种异常情况产生,那么throw后面可以写多个异常类,用逗号隔开
public static int getElement(int[] arr,int index)
throws NullPointerException, ArrayIndexOutOfBoundsException{
if (arr==null){
throw new NullPointerException("空指针");
}
if (index<0 || index>=arr.length){
throw new ArrayIndexOutOfBoundsException("数组越界");
}
int element = arr[index];
return element;
}
public static void main(String[] args) {
int[] arr = {1,2,3};
int num= Throws2.getElement(null,3);
System.out.println("num:"+num);
}
}
运行时期异常
RuntimeException和他的所有子类异常,都属于运行时期异常NullPointerException,ArrayIndexOutOfBoundsException等都属于运行时期异常- 运行时期异常的特点
- 方法中抛出运行时期异常,方法定义中无需 throws 声明,调用则也无需处理此异常.
- 运行时期异常一旦发生,需要程序人员修改源代码
class ExceptionDemo{
public static void main(String[] args){
method();
}
public static void method(){
throw new RuntimeException();
}
}
异常中常用的方法
- 在
Throwble类中为我们提供了很多操作异常对象的方法,常用的如下:
- getMessage方法 : 返回该异常的详细信息字符串,即异常提示信息
- toString方法 : 返回该异常的名称与详细信息字符串;
- printStackTrace : 在控制台输出该异常的名称和详细信息字符串,异常出现的代码位置
自定义异常
public class 异常名 extends Exception {
public 异常名(){
}
public 异常名(String s){
super(s)
}
}