• java 通过异常处理错误


    java的基本理念是"结构不佳的代码不能够运行"

    一.概念 

       发现错误的理想时机是编译阶段,然而,编译期间并不能找出所有的错误,余下的问题必须在运行时期解决。

    二.基本异常

       异常情形(exceptional conditin)是指阻止当前方法或作用域继续执行的问题.

       普通问题是指在当前环境下能得到足够的信息,总能处理这个错误

       当抛出异常后,有几件事会随之发生。首先,同Java中其它对象的创建一样,将使用new在堆上创建异常对象。然后,当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用。此时,异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理程序,它的任务是将程序从错误状态中恢复,以使程序要么换一种方式运行,要么继续运行下去。

    if(t == null)
       throw new NullPointerException();//这样就把错误信息传播到更大的环境中,

    三. 异常参数

        与使用java中的其它对象一样,我们总事用new再堆上创建异常对象,这也伴随着存储空间的分配和构造器的调用,所有标准异常都有两个构造器:一个是默认构造器,一个是接受字符串作为参数,以便能把有关信息放入异常对象的构造器;   

       关键字throw将产生许多有趣的结果,在使用new创建了异常对象之后,此对象的引用将传给throw.尽管返回的异常对象其类型通常与方法设计的返回类型不同,但从效果上看,它就像方法的返回,可以简单的把异常处理看成一种不同的返回机制,当然若过分的强调这种类比的化,就会有麻烦了.  另外还能用抛出异常的方式从当前的作用域退出,在这两种情况下,将会返回一个异常处理对象,然后退出方法或作用域

     抛出异常与方法正常返回值的相似到此为止,因为异常返回和普通方法返回的地点完全不同

      此外,能够抛出任意类型的Throwable对象,它是异常的根类,通常,对于不同的错误,要抛出相应的异常,错误处理信息可以保存在异常对象内或用异常类的名称来暗示.上异常环境通过这些信息来决定如何处理异常

     四. 捕获异常

        要明白异常时如何被捕获的,必须理解监控区域(guarded region)的概念,它时一段可能产生异常的代码,并且后面跟着处理这些异常的代码

    Exception从基类Throwable继承的方法有

    • String getMessage(): 详细信息
    • String getLocalizedMessage(): 本地语言描述详细信息
    • void printStackTrace(): 调用栈显示了"把你带到异常抛出地点"的方法调用序列,输出到标准输出.
    • void printStackTrace(PrintStream): 调用栈显示了"把你带到异常抛出地点"的方法调用序列,输出到要输出的流.
    • void printStackTrace(java.io.PrintWriter): 调用栈显示了"把你带到异常抛出地点"的方法调用序列,输出到要输出的流.
    • Throwable fillInStackTrace(): 用于在Throwable对象的内部记录栈帧的当前状态.

    栈轨迹:

    printStackTrace()方法所提供的信息可以通过getStackTrace()方法直接访问.

    getStackTrace()方法返回一个由根轨迹中的元素所构成的数组,每一个元素都表示栈中的一帧.

    1.  try块

    如果在方法内部抛出异常后,这个方法将在抛出异常的过程中结束,如果不想就此结束,可以设置一个try块来捕获异常

    try{
       //Code that might generate exception
    }

    2.异常处理程序

        异常处理程序紧跟在try块之后,以关键字catch表示,异常处理程序必须紧跟在try块之后,当异常被抛出时,异常处理机制将负责搜寻参数与异常类型想匹配的第一个处理程序,然后进入catch子句执行,此时认为异常得到了处理,一旦catch子句结束才处理程序的查找过程结束,并不会在调用其它catch子句.

       异常处理模型

       终止模型:错误非常关键,一旦异常被抛出,即终止程序

       恢复模型:意思是异常处理程序的工作是修正错误,然后重新尝试调用出问题的方法,并认为第二次可以成功.如果要用java实现类似的恢复行为,那么在遇到错误时,就不能抛出异常,而时调用正确的方法来修正该错误,或者把try块放进一个while循环里,这样就不断进入while块,直到得到满意的结过

    package object;
    
    public class Cure {
        public static void main(String[] args) throws Exception
        {
            int i =5;
            while(i-->0)
            try {
                    
            }catch(Exception e)
            {
                e.printStackTrace();
            }finally {
                System.out.println(i);
            }
        }
    }

    五. 创建自定义异常

     要自定义异常,必须从已有的异常类继承,最好是选择意思相近的异常类继承(不过这样的异常并不容易找),建立新的异常类型最简单的方法就是让编译器为你产生默认构造器,所以这几乎不用写多少代码:

    package exceptions;
    //: exceptions/InheritingExceptions.java
    // Creating your own exceptions.
    
    class SimpleException extends Exception {} //必须是throwable子类
    
    public class InheritingExceptions {
      public void f() throws SimpleException {
        System.out.println("Throw SimpleException from f()");
        throw new SimpleException(); //这里抛出异常SimpleException
      }
      public static void main(String[] args) throws SimpleException{
        InheritingExceptions sed = new InheritingExceptions();
        try {
          sed.f();
        }catch(SimpleException e) //这里捕获异常SimpleException,并执行catch子句
        {
            System.out.println("caught it!");
        }
      }
    } /* Output:
    Throw SimpleException from f()
    Caught it!
    *///:~

    编译器创建了默认构造器,它将自动调用基类的默认构造器,一般不会用Excetption(String)这样的构造器,这种构造器不实用,对异常来说最重要的是类名

      也可以通过写入System.err而将错误发送给标准错误流,通常这比System.out要好,因为System.out可以被重定向

    package exceptions;
    //: exceptions/FullConstructors.java
    
    class MyException extends Exception {
      public MyException() {}
      public MyException(String msg) { super(msg); }//super调用类基类构造器,它结受一个字符串为参数
    }
    
    public class FullConstructors {
      public static void f() throws MyException {
        System.out.println("Throwing MyException from f()");
        throw new MyException();
      }
      public static void g() throws MyException {
        System.out.println("Throwing MyException from g()");
        throw new MyException("Originated in g()");
      }
      public static void main(String[] args) {
        try {
          f();
        } catch(MyException e) {
          e.printStackTrace(System.err);//将错误发送给标准错误流
    //e.printStackTrace()//直接默认的话错误也是发送给标准错误
    } try { g(); } catch(MyException e) { e.printStackTrace(System.out);//将错误发送到System.out ,System.out.可以重定向 } } } /* Output: Throwing MyException from f() exceptions.MyException Throwing MyException from g() exceptions.MyException: Originated in g() at exceptions.FullConstructors.f(FullConstructors.java:12) at exceptions.FullConstructors.main(FullConstructors.java:20) at exceptions.FullConstructors.g(FullConstructors.java:16) at exceptions.FullConstructors.main(FullConstructors.java:25) *///:~
  • 相关阅读:
    【Java面试题】52 java中会存在内存泄漏吗,请简单描述。
    【Java面试题】51 什么时候用assert。
    JS 生成GUID 方法
    最全html5 meta设置详解 (转)
    前端开发工程师 调试方法合集
    [超级懒人最简单法]iPhone 6 plus 适配切图方法分享(转载文章)
    H5移动前端开发常用高能css3汇总
    前端性能监控方案window.performance 调研(转)
    微信浏览器取消缓存的方法
    H5移动APP开发 细节详解(转)
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10292902.html
Copyright © 2020-2023  润新知