zoukankan      html  css  js  c++  java
  • Java异常处理机制

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

    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在堆上建立的,垃圾回收器会自动将他们清理掉。

  • 相关阅读:
    【探路者】团队Alpha周贡献分数分配结果
    2017秋-软件工程第七次作业-第八周例行总结
    2017秋-软件工程第七次作业(2)-【探路者】Alpha周(2017年10月19)贡献分配规则和分配结果
    2017秋-软件工程第七次作业(1)-【探路者】贪吃蛇阿尔法发布展示(视频展示)
    2017秋-软件工程第七次作业(1)-【探路者】贪吃蛇阿尔法发布
    名词1
    Jsp1
    代码,python1
    关于键盘
    代码,java_web
  • 原文地址:https://www.cnblogs.com/silence-hust/p/4483951.html
Copyright © 2011-2022 走看看