文章目录
  1. 1. 一、异常类型
  2. 2. 二、捕获异常语句
  3. 3. 三、自定义异常类

  异常允许我们强制停止程序运行,并告诉我们出现了什么问题,或者强制程序去处理问题,并返回到稳定状态。

  Java提供一个Throwable类,该类是所有异常和错误类的超类。只有当对象是此类的实例时,才能通过Java虚拟机或者Java的throw语句抛出。throwable类及其子类的结构图:

一、异常类型

  Error:一般是指严重的系统错误,与虚拟机相关的问题,如系统崩溃,虚拟机出错,动态链接失败等,这一类的错误一般无法修复或不可能捕获,将导致应用程序中断。

  Exception:是指一些可以捕获且可能恢复的异常情况,如数组下标越界ArrayIndexOutOfBoundsException、数字被零除产生异常ArithmeticException、输入输出异常IOException等。

  可以知道Error属于JVM需要负担的责任,RuntimeException类是程序应该负担的责任,受检异常是具体应用负担的责任。作为程序员关心的就是Exception。

1、非受检异常

  是指编译器不要求强制处置的异常,一般是编程时的逻辑错误,是程序员应该避免的,RuntimeException类以及他的子类都是非受检异常的,具体如下:

  1)错误的类型转换:ClassCastException

  2)组下标越界:ArrayIndexOutOfBoundsException

  3)空指针访问异常:NullPointerException

  4)被零除产生异常:ArithmeticException

2、受检异常

  编译器要求必须处置的异常,及程序运行时由于外界因素造成的一般性异常,具体如下:

  1)没有找到具体指定名称的类异常:ClassNotFoundException

  2)访问不存在的文件异常:FileNotFoundException

  3)操作文件异常:IOException

  4)操作数据库时发生异常:SQLException

  Java要求Java程序必须捕获或声明所有的受检异常,对于这类异常,如果程序不做处理,则将会带来意想不到的结果,而非受检异常可以不做任何处理。   

二、捕获异常语句

  1、try……catch……finally……

  try选定要捕获异常的范围,在执行时,catch后面括号内的代码会产生异常对象并抛出,然后用catch块来处理异常。

  finally不管是否有异常发生都要执行的语句块,如数据库的关闭。要注意:如果try语句块中有一个明确的return语句,finally快也总是在return前执行。

  2、throws 和 throw

  throw:语句明确的抛出一个异常,必须是一个throwable 的类,或者new来创建一个实例:throw new XXException();

  执行throw语句后,运行流程将立即停止throw的下一条语句也将暂停执行。

  throws:如果一个方法a可以引发异常,而他本身并不对该异常进行处理,那么a方法必须将这个异常抛给调用方法,以使程序能够继续执行下去。用法:method()throws   Exception1,Exception2,。即throws用来声明一个方法可能会抛出的所有异常,如果一个方法声明的是受检异常,那么调用这个方法的类必须处理这个异常。可以使用try……catch……来捕获,也可以在该方法上声明throws。  

public static void main(String[] args) {
    // TODO Auto-generated method stub
    int number = 0;
    try {
        System.out.println("aaaaaaaa");
        number = Integer.parseInt(args[0]);
        System.out.println("bbbbbbbb");
    } catch (Exception e) {
        // TODO: handle exception
        throw new ArrayIndexOutOfBoundsException("out of bounds");
        //System.out.println("非法的数字");
    }
    finally{
        System.out.println("你输入的数字为:"+number);
    }
} 

结果:

 aaaaaaaa

  你输入的数字为:0

  Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException:
out of bounds

  at com.wt.others.ThrowTest.main(ThrowTest.java:12)

  原理:但抛出异常后将使用使用new在堆上创建异常对象,然后你的执行路径被终止,并且从当前环境中弹出对异常对象的引用,此时异常处理机制接管程序,并开始找一个恰当的地方执行程序,这个恰当的地方就是异常处理程序,它的任务就是将程序从错误状态中恢复。

public static void main(String[] args) {
    testThrows(args);
}
public static void testThrows(String[] tmp) {
    try {
        createThrows(tmp);
    } catch (Exception e) {
        // TODO: handle exception
        System.out.println("come from createThrows ");
    }
}
public static void test2Throws(String[] tmp) throws Exception {
    createThrows(tmp);
}
public static void createThrows(String[] tmp){
    int num = 0;
    num = Integer.parseInt(tmp[0]);
    System.out.println("你输入的数字为:"+num);
}

  throws和throw可以组合在一起使用,就是在捕获异常后抛出一个明确的异常个调用者。

二者的区别:

  throw是用在方法中的,throws是用在方法签名之后的,在同一个地方使用这些的时候要注意,throws抛出异常的类型范围要比throw的大才行。  

public static void main(String[] args) {
    try {
        methodA();
    } catch(Exception e)  {
        // TODO: handle exception
        System.out.println(e.getMessage());
    }
    methodB();
}
public static void methodA() {
    try {
        System.out.println("come in A");
        throw new RuntimeException("制造异常");
    } finally  {
        // TODO: handle exception
        System.out.println("用A的finally ");
    }
}
public static void methodB() {
    try {
        System.out.println("come in B");
        return;  //这里返回,在执行完finally语句后才返回
    } finally  {
        // TODO: handle exception
        System.out.println("用B的finally ");
    }
}

结果: 

  come in A

  用A的finally

  制造异常

  come in B

  用B的finally

  3、getMessage和printStackTrace方法

  getMessage:返回此throwable对象的详细消息字符串

  printStackTrace:将此throwable对象及其追踪输出至标准错误流

try{
fun();
}catch(Exception e){
e.getMessage(e);
// e.printStackTrace(e);
}

三、自定义异常类

  一般都选择Exception作为父类,如下:

public class MyException extends Exception{
public MyException(){
    super();
}
public MyException(String msg){
    super(msg);
}
public MyException(Throwable cause){
    super(cause);
}
public MyException(String msg,Throwable cause){
    super(msg, cause);
}
}

  其实并不是所有的异常都需要处理,异常处理会占用一定的资源,影响程序的执行效率。认真观察异常的名字和行号,尽量减少try语句块的体积,在处理异常的时候应该打印出该异常的堆栈信息以方便调试使用。

  对异常对象的清理并不需要过多的关心,因为他们都是用new在堆上建立的,垃圾回收器会自动将他们清理掉。

文章目录
  1. 1. 一、异常类型
  2. 2. 二、捕获异常语句
  3. 3. 三、自定义异常类