异常机制除了报错,还有其他功能吗?
编写程序,什么时候会用到它

解决方案 »

  1.   

    异常机制就是用来处理错误的
    异常分为 Error类和Exception类
    error 是系统错误 我们无法处理
    exception分类 运行异常和非运行异常 运行异常可不捕获 
    非运行异常必须要捕获异常机制 是为了给客户提供更好的错误提示信息
      

  2.   

    io操作的时候必须要有异常检测,否则无法通过编译。因为io操作为异常经常发生的环节。
      

  3.   

    try-catch是java基本功,也是考验java开发能力的地方什么地方try-catch,什么时候try-catch,catch后的处理,是直接抛出,还是留在本模块内处理,catch哪些异常,而忽略哪些异常......建议看一下JDK里面的IO容器类的源代码
      

  4.   

    除了运行时异常(Runtime),其它的异常都必须用try-catch捕获,这样可以提高程序的可靠和可控性。
    具体查看JDK的API文档,每种方法都有声明是否抛出异常的,如果抛出的不是运行时异常就必须用try-catch捕获。
      

  5.   

    他抛出异常,我就要catch,可我的处理代码里什么也没写啊。这不跟没处理一样嘛,为什么还得catch啊。catch里不写代码不久相当于没处理吗?
    谁回答?
      

  6.   

    你这也是处理了,表示这个异常没什么影响;
    这个跟不知道怎么处理不一样, 不知道怎么处理时就不会catch, 直接让上层来处理;
      

  7.   

    有没有可能try中代码执行而catch中的代码不执行的情况?
      

  8.   

        异常类的根类是Throwable,他的直接子类有Error,Exception,Error是系统的内部错误,一般程序员处理不了,如果程序中抛出Error的异常,编译是不能通过的。而Exception则是我们可以处理的异常。Exception类里又分两类:一种是RuntimeException,一种是其他的Exception,RuntimeException是一种经常会出现的错误,这种错误可以catch处理,也可以不catch,而剩下的Exception则是必须进行catch的Exception。
        JAVA异常处理的抛出异常的throw和throws这两个关键字的区别:throws写在定义一个方法名的后面,表示若该方法出现异常时将异常抛给调用他的地方;throw写在具体的方法内部,用来抛出异常进而可以被try...catch()语句捕获;
    情况一:
    try {
    new Exception();
    System.out.println("ok");
    } catch(Exception e) {
    System.out.println("exception");
    } finally {
    System.out.println("finally");
    }
    打印结果:ok
    finally
    说明:千万不要以为new Exception()会抛出异常,这里只是简单new了一个Exception实例而已。
    情况二:
    try {
    throw new Exception();
    System.out.println("ok");
    } catch(Exception e) {
    System.out.println("exception");
    } finally {
    System.out.println("finally");
    }
    结果:编译不通过,throw new Exception();语句后面System.out.println("ok");的区域都视为不可到达代码段Unreachable Code
    情况三:
        public class TestExceptionPrint {
    public static void aMethod() throws Exception {
    try {
    throw new Exception();
    } catch(Exception e) {
    System.out.println("Method Exception");
    } finally {
    System.out.println("finally");
    }
    }
    public static void main(String[] args) {
    try {
    aMethod();
    System.out.println("Main NoException!");
    } catch(Exception e) {
    System.out.println("exception!");
    }
    System.out.println("finished");
    }
    }
    打印结果:
    Method Exception
    finally
    Main NoException!
    finished
    结果说明:aMehtod里面抛出了异常,但是由于方法里对其有进行捕获catch,所以异常不会传到main方法里,于是main方法就正常执行了。下面来看aMethod方法里没有对异常进行catch的情况:
    情况四:
    package com.yilong.scjp.test;
    public class TestExceptionPrint {
    public static void aMethod() throws Exception {
    try {
    throw new Exception();
    } finally {
    System.out.println("finally");
    }
    }
    public static void main(String[] args) {
    try {
    aMethod();
    System.out.println("Main NoException!");
    } catch(Exception e) {
    System.out.println("exception!");
    }
    System.out.println("finished");
    }
    }
    打印结果:
    finally
    exception!
    finished
    结果说明:由于aMethod方法里没有对异常进行捕获,于是异常传递到了Main方法里。除此之外,还可以看到在try…catch里面一旦捕获到异常,那么在该块里面剩下的语句就不会再被执行到(Main NoException没有被打印),但是在出了try…catch语句块后就又会被执行了(finished被打印了)。
        另外在实际中,我们还可以创建自己的异常类,只要继承Exception类就可以了,如:public class TestException { public static void main(String[] args) {
    int i = 0;
    if(i == 0) {
    try {
    throw new MyException("" + i);
    } catch (MyException e) {
    System.out.println("Catch Some Exception!");
    } finally {
    System.out.println("end");
    }
    }
    System.out.println("main end");
    }
    }class MyException extends Exception {
    MyException() {
    System.out.println("Exception!");
    }

    MyException(String s) {
    System.out.println("Some Exception Throwed!" + " " + s);
    }
    }
      

  9.   

    由于本文旨在探讨Java"异常机制"的深层原理,因此关于"异常"的使用方法都不做详细说明。首先看一段非常熟悉的用于打开一个文件的C程序段:  FILE *fp;  fp=fopen(filename,"rw");  if(fp==NULL){  printf("cannot open file\n");  exit(0);  }  在这段程序中,if条件语句中的一段用来处理没有找到指定文件,或者其它原因无法正确打开指定文件。可是如果遇到一个责任心不强的程序员,他可能认为出现找不到文件的可能性很小,或者由于思路集中在程序功能的实现上而忘记了处理这种情况。这时程序同样可以正确编译,而且一般情况下也不会出现问题。但此时这段程序可以肯定说是不够健壮的,而且一旦这段程序发生了错误也会让程序员很难发现错误出在哪里。在C语言以及其它大多数高级语言中都可以举出很多这种例子。  也就是一个函数在使用的时候,可能会出现并没有达到这个函数的使用目的的情况,哪怕在这段程序的特定使用环境下发生这种异常情况的可能性只有万分之一。常用处理的方法就是,程序员在需要使用某个函数时必须充分了解可能会有什么原因导致该函数不能正确执行,然后加入相应的条件判断语句来进行处理。后面将有一个例子说明这个问题。  而Java的" 异常机制"就是在处理上述问题中给了程序员非常简单而灵活的方式。一般来说,其它高级语言主要是让函数使用者来关注该函数可能会出现的异常情况,而 java则是把这件事情交给方法(和函数对应的概念,在Java中称方法)的设计者来做。这对于方法的使用者来说带来的方便是不会因为责任心不强,或者办事丢三那四,会忘了在使用方法时处理可能发生的异常情况。而麻烦就是,在使用一个可能会发生异常的方法时,绝对不能视而不见,而必须做出相应的处理。也就是说象上述C程序段中,如果忘了if程序块,这个程序甚至还能蒙过一个外行上司,但当使用Java来完成这个功能时,只要用到的方法使用了"异常"机制,如果不对可能产生"异常"的方法进行相应处理,java编译器是不会让其通过的。  一、"异常类"的组织形式  Java系统类中的方法产生的异常都被组织成"异常类"(还有Error类,不在本文讨论范围),此方法和它相关的"异常类"通过throws 关键字关联在一起,并且这些类都必须是Exception类的子类。任何一个自己开发的类的方法中如果可能会产生某种异常,也可以将这种异常组织成一个" 异常类",但这个"异常类"同样必须是Exception的子类,或孙子类等等。  例1:  /*isLegal于检查数据是否合法,当>0时视为合法,返回合法值,  *否则视为不合法,抛出"异常".*/  int isLegal(int dt) throws LowZeroException//这种定义本文中均称为方法与"异常"通  {                  //过throws建立了关联  if(dt>=0){  return data;  }  else  throw new LowZeroException();  }  /*自已写的异常类,继承自Exception*/  class LowZeroException extends Exception  {  public LowZeroException(){  super();  }  }  仔细观察方法isLegal(),它体现出的最值得注意的特色是,它有两种方式的函数出口,一种是通过return语句,返回的是方法本身定义的类型的实例,另一种是通过throw,返回的是"异常类"的对象实例,Java中称之为抛出"异常".对比一下C中如何处理同样的问题的:  int isLegal(int dt) {  if(dt>=0){  return data;  }  else  return -1;//通过一个特定值来表明出错  }  由于C只能通过return返回函数值,所以在处理异常情况时则可能通过以上方式来处理。当然这就要求isLegal()函数的使用者必须知道函数中使用返回值-1来表明出现不合法数据的情况。  对比这两种处理方法,可以知道java的"异常机制"把处理异常事件的职能和方法本身的职能通过两个不同出口分离开来。  所有这些"异常类"独立于它具体服务的方法被统一组织成一个类树。"异常机制"就好比高校的后勤社会化一样,通过后勤社会化将学校的教学职能和学校的后勤保障分离开来,并且后勤集团的组织形式也是独立于学校主体的。事实证明,这种组织方式不仅提高了服务效率,也提高了服务质量。整个Java体系中的"异常类"组织形式如图1所示:  在例1中的isLegal()方法如果在调用过程中没有能正常返回整形数,而是在"异常"产生点产生了"异常"对象,那么这个"异常"对象由谁来接收,并处理它呢?以下就来解答这个问题。  二、"异常"的处理过程  Java中由try…catch语法来处理"异常",将关联有"异常类"的方法包含在try{}程序块中,catch(){}关键字可以使用形参,用于和方法产生的"异常"对象结合。当调用某个方法时,引起异常事件发生的条件成立,便会抛出"异常",原来的程序流程将会在此方法处中断,然后 try模块后紧跟的catch中的"形参"和此异常对象完成了结合,继而进入了catch模块中运行。具体过程举例说明:  例2:  /*将关联有异常的方法包含在try模块中*/  int myMethod(int dt){  int data = 0;  try{  int data = isLegal(dt);  }catch(LowZeroException e){  System.out.println("发生数据错误!");  }  return data;  }  三、"异常"的处理方法  有两种方法处理"异常":第一种如例2,将含有"异常"出口的方法直接放到try块中,然后由紧随其后的catch块捕捉。第二种是不直接监听捕捉被引用方法的"异常",而是将这个"异常"关联传递给引用方法,同时监听捕捉工作也相应向上传递。  例3:  int myMethod2(int dt)  {  int data = 0;  try{  data = myMethod(dt)  }catch(LowZeroException e){  System.out.println("发生数据错误!");  e.printStackTrace();  }  return data;  }  int myMethod(int dt) throws LowZeroException  {  int data = isLegal(dt); //此处引用isLegal()方法,但并没有捕捉它的"异常"  return data;  }  从上例中可以看到方法myMethod()与它引用的方法isLegal()产生的"异常"LowZeroException建立了关联,也就是完成了将"异常"关联的向上传递,此时的myMethod()方法体中虽然只有一个return返回语句,但它事实上同样有两种方式的函数出口,一种是由return返回的整形值,另一种则是返回方法名中的throws关键字所指的"异常类"的实例对象。相应的,监听捕捉的工作交给了上一层方法 myMethod2()。同样的道理,myMethod2()也可以将"异常"通过throws的关联继续向上传递。这样的话,一旦一个"异常"被捕捉到时,这个"异常"必有一个传递路径,而如果我们在捕捉点的catch程序块中加入printStackTrace()方法,便能清楚的看到这个"异常"是怎样传递过来的。例如在例3如果有"异常"被捕捉到,e.printStackTrace()打印出来的结果将是:  LowZeroException:  at Example.isLegal  at Example myMethod  at Example.myMethod2  at Example main  从上结果中我们可以看到,从LowZeroException"异常"产生点,即包含throw new LowZeroException();子句的方法开始,然后一直追溯到产生当前线程的方法(注意:printStackTrace()并不是追溯到捕捉点结束,而是到产生当前线程的方法结束)。"异常"产生点产生的LowZeroException"异常"对象,首先被赋给了isLegal()关联的 LowZeroException类的无名引用,然后继续赋给myMethod()关联的LowZeroException类的无名引用,再继续赋给 myMethod2()中的catch块中的形参e,最后在这里被处理掉,这个"异常"对象随即消失。可以说,catch(){}就是"异常"对象的生命终结点。  另外还要注意一点,方法与"异常"的关联可以一直向上传递,当传递到与main方法关联后,即在main()方法的定义中使用了throws Exception,这时除了虚拟机没有其它方法能够引用main()方法,且在程序中可能看不到try…catch程序块,但并不会产生错误,因为此时虚拟机会捕捉"异常",并且会默认的调用printStackTrace()方法打印出"异常"路径。总之只要一个方法关联了"异常",可以将这个"异常 "关联向上传递,但是最终必须使用catch来终止"异常",或者一直传递到main()方法交给Java虚拟机来结束"异常"对象的生命,否则是通不过编译的。  四、使用"异常机制"的需要注意的几点  1.一个方法中可能会产生多种不同的异常,你可以设置多个"异常"抛出点来解决这个问题。  2."异常"对象从产生点产生后,到被捕捉后终止生命的全过程中,实际上是一个传值过程,所以你可以根据需要,来合理的控制检测到"异常"的粒度。例如在例3中,如果你并不需要知道具体产生的是LowZeroException"异常",那么你可以使用"异常"的公共父类Exception来结合"异常"对象,即catch(Exception e){…}.同样在"异常"与方法关联的传递过程中,也可以根据需要控制关联"异常"的粒度,即throws后面跟上异常对象的父类名。  3."异常机制"中还有一种特殊情况――RuntimeException"异常类",这个"异常类"和它的所有子类都有一个特性,就是"异常 "对象一产生就被Java虚拟机直接处理掉,即在方法中出现throw 子句的地方便被虚拟机捕捉了。因此凡是抛出这种"运行时异常"的方法在被引用时,不需要有try…catch语句来处理"异常".