Java中的异常处理机制已经比较成熟,我们的Java程序到处充满了异常的可能,如果对这些异常不做预先的处理,那么将来程序崩溃无从调试,很难找到异常所在的位置。本文将探讨一下Java中异常与错误的处理方法,一起来看看。
  异常与错误:
  异常:

  在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它。Java中使用异常类来表示异常,不同的异常类代表了不同的异常。但是在Java中所有的异常都有一个基类,叫做Exception。
  错误:
  它指的是一个合理的应用程序不能截获的严重的问题。大多数都是反常的情况。错误是VM的一个故障(虽然它可以是任何系统级的服务)。所以,错误是很难处理的,一般的开发人员(当然不是你)是无法处理这些错误的,比如内存溢出。和异常一样,在Java中用错误类来表示错误,不同的错误类代表了不同的错误。但是在Java中所有的错误都有一个基类,叫做Error。
  综上,我们可以知道异常和错误本质的区别是异常能被开发人员处理而错误时系统本来自带的,一般无法处理也不需要我们程序员来处理。
  1.一个异常是在一个程序执行过程中出现的一个事件,它中断了正常指令的运行
  2.错误,偏离了可接受的代码行为的一个动作或实例
  异常的结构分类:
  1、运行时异常(未检查异常)
  2、编译时异常(已检查异常)
  运行异常即是RuntimeException;其余的全部为编译异常
  在Java中异常Exception和错误Error有个共同的父类Throwable。
  Error Exception
  runtimeException几个子类
  1、java.lang.ArrayIndexOutOfBoundsException
  数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
  2、java.lang.ArithmeticException
  算术条件异常。譬如:整数除零等。
  3、java.lang.NullPointerException
  空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
  4、java.lang.ClassNotFoundException
  找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
  对异常的处理:
  try{}catch{}
  try{}catch{}finally{}无论有无异常finally代码块都会被执行
  try{}finally{}也是可以组合使用的但是catch{}finally{}不可以
  注意:在继承关系中,子类覆盖父类的方法,抛出异常的范围不能比父类更宽泛
  异常的使用
  在异常的使用这一部分主要是演示代码,都是我们平常写代码的过程中会遇到的(当然只是一小部分),抛砖引玉吗!
  例1.这个例子主要通过两个方法对比来演示一下有了异常以后代码的执行流程。
  public static void testException1(){
  int[]ints=new int[]{1,2,3,4};
  System.out.println("异常出现前");
  try{
  System.out.println(ints[4]);
  System.out.println("我还有幸执行到吗");//发生异常以后,后面的代码不能被执行
  }catch(IndexOutOfBoundsException e){
  System.out.println("数组越界错误");
  }
  System.out.println("异常出现后");
  }
  /*output:
  异常出现前
  数组越界错误
  常出现后
  */
  public static void testException2(){
  int[]ints=new int[]{1,2,3,4};
  System.out.println("异常出现前");
  System.out.println(ints[4]);
  System.out.println("我还有幸执行到吗");//发生异常以后,他后面的代码不能被执行
  }
  首先指出例子中的不足之处,IndexOutofBoundsException是一个非受检异常,所以不用try…catch…显示捕捉,但是我的目的是对同一个异常用不同的处理方式,看它会有什么不同的而结果(这里也只能用它将一下了)。异常出现时第一个方法只是跳出了try块,但是它后面的代码会照样执行的。但是第二种不一样了直接跳出了方法,比较强硬。从第一个方法中我们看到,try…catch…是一种”事务性”的保障,它的目的是保证程序在异常的情况下运行完毕,同时它还会告知程序员程序中出错的详细信息(这种详细信息有时要依赖于程序员设计)。
  例2.重新抛出异常
  public class Rethrow{
  public static void readFile(String file)throws FileNotFoundException{
  try{
  BufferedInputStream in=new BufferedInputStream(new FileInputStream(file));
  }catch(FileNotFoundException e){
  e.printStackTrace();
  System.err.println("不知道如何处理该异常或者根本不想处理它,但是不做处理又不合适,这是重新抛出异常交给上一级处理");
  //重新抛出异常
  throw e;
  }
  }
  public static void printFile(String file){
  try{
  readFile(file);
  }catch(FileNotFoundException e){
  e.printStackTrace();
  }
  }
  public static void main(String[]args){
  printFile("D:/file");
  }
  }
  异常的本意是好的,让我们试图修复程序,但是现实中我们修复的几率很小,我们很多时候是用它来记录出错的信息。如果你厌倦了不停的处理异常,重新抛出异常对你来说可能是一个很好的解脱。原封不动的把这个异常抛给上一级,抛给调用这个方法的人,让他来费脑筋吧。这样看来,java异常(当然指的是受检异常)又给我们平添很多麻烦,尽管它的出发点是好的。
  例3.异常链的使用及异常丢失
  ExceptionA,ExceptionB,ExceptionC
  public class ExceptionA extends Exception{
  public ExceptionA(String str){
  super();
  }
  }
  public class ExceptionB extends ExceptionA{
  public ExceptionB(String str){
  super(str);
  }
  }
  public class ExceptionC extends ExceptionA{
  public ExceptionC(String str){
  super(str);
  }
  }