Java中的异常及异常处理

异常的概述

异常是运行时期发生的不正常情况
在其他语言中,例如C中,对于这种不正常的情况用条件语句判断筛选

在Java语言中用类的形式对不正常情况进行了描述和封装对象,

  • 以前正常流程代码和问题处理代码相结合
    if(num>0){
    //问题处理代码块
    }
  • 现在Java把常流程代码和问题处理代码分离,增加了阅读性
    if(num>0){
    抛出异常
    }
    简而言之 ,异常就是Java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述(不同的类用不同的类进行描述,例如索引越界,非法引用空指针等)

在编程中,出现的问题有很多,因此描述问题的异常类也很多,我们就把异常向上归纳,形成了异常体系

Throwable父类(可抛出的,是这个类的子类对象才可以抛出)

1. 一般不可以处理的(Error)是由JVM抛出的严重性问题,一般不做处理直接修改程序
2. 可以处理的(Exception)

异常类体系

class Demo{
 public void show(int[] args,int index){
  System.out.println(args[index]);
}
}
class ExceptionDemo{
 public static void main(String[] args){
int[] args = new int[3];
Demo demo = new Demo();
demo.show(args,3);
}

过程:由于数组越界,在第三行JVM加了一个throw new ArrayIndexOutOfBoundsException(index),抛出一个数组越界的异常,抛给它的调用者,也就是主函数,因为主函数没有处理办法,又抛给了它的调用者JVM,到JVM就抛不出去了,JVM 启动默认的异常处理机制(全都放在控制台上让程序员看到,来解决)。

真实开发的时候这些东西先存起来,日志,定期的查看。

异常处理

throw与throws的用法

注意:如果让一类称为异常类,必须要继承异常体系,因为只有成为异常体系的子类才有资格具备可抛性(才可以被两个关键字所操作 throw throws)

class FuNumException extends Exception    规范上继承了Exception后缀加一个Exception
{                                            继承Error类后缀加Error
  FuNumException()
{
}
}
public int method(int[] arr,int index) throws FuNumException  //
{
if(arr  == null)
      throw new NullPointerException("非法引用空指针");
if(index >= arr.length)
      throw new ArrayIndexOutofBoundsException("数组越界");
if(index < 0)
     throw new FuNumException();
}

如果函数内发生了异常,需要在函数上声明,否则编译失败
如果一个函数调用了抛出异常的函数,这个函数需要处理异常,处理的方式:1.抛出(声明此函数会抛出异常,throws关键字) 2.捕捉

throws与throw的区别

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

异常的分类

这里为什么我们自定义的异常类被声明标出,而另外两个内部异常类没有声明标出就可以通过编译?
这得异常的分类说起:

  • 编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系
  • 编译时不检测异常(运行时异常):Exception中的RuntimeException和其子类

因为上述代码中 FuNumException是继承的Exception,所以它是编译被检测异常,如果不做处理,必编译失败,而NullPointerException,ArrayIndexOutofBoundsException是RuntimeException体系中的,不做处理也可以编译成功。


异常继承树

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

捕捉异常(try catch语句)

之前函数内部发生异常,我们的处理办法是在函数后面声明异常,接下来我们讲到另一种处理方式,捕捉异常

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

具体格式

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

try和catch必须一起写(没catch就相当于没处理)
如果在一个函数中抛出多个异常,调用它的函数可以有多个 catch来处理不同的异常对象

try{
//需要被检测异常的代码;
}

catch(异常类 变量) //该变量用于接收发生的异常对象
{
//处理异常的代码
}
catch(异常类 变量) //该变量用于接收发生的异常对象
{
//处理异常的代码
}

有多个catch出现时,从上到下来执行catch,所以上面catch的异常类应该在继承树下面的异常类,如果最上面的异常类是Exception,那么直接由于多态,直接执行第一个catch

异常处理的原则

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

finally语句块

一定会执行的代码
即使在catch语句中加入return,发生异常后,仍然可以执行finally代码块。

一种情况除外把return换成System.exit(0);//推出JVM

finally作用

连接数据库之后,在查询中出现异常(程序停止),需用finally关闭数据库连接。

try catch finally代码块组合特点

  • try catch finally
  • try catch(多个)当没有必要资源释放时,可以不用finally
  • try finally 没有catch相当于没处理异常,还需要在函数上面声明异常(throws),用于异常无法直接catch处理,但是资源需要关闭

你可能感兴趣的:(Java中的异常及异常处理)