关于Exception学习

1. 可以灵活的处理异常,如果当前方法有能力处理异常,就捕获并处理它,否则只需抛出异常,由方法调用者来处理它。
      a) 事实上,异常还有一个非常有用的作用,可以用它来做流程控制。
2. 
在Java编程语言中,用try和catch语句来处理异常。格式如下:<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> </v:shapetype>

<v:shapetype coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype>
 
  try {
    // code that might throw a particular exception
  } catch (SpecialException e) {
    // code to execute if a SpecialException  is thrown
  } catch (Exception e) {
 //code to execute if a general Exception exception is thrown
 }
---------------------------------------------------------------------------------------------------------------
关键字throws 指出方法有可能抛出的异常,如果方法有可能抛出多个异常,可以在throws后添加多个异常,声明抛出多个异常
例如:methodName throws Exception1,Exception2,Exception3

Throwable是所有异常类的父类,继承自Object类。Throwable又分为两种(Error,Exception,均继承自Throwable);
Error :用来表示编译时和系统错误
Exception : 可以抛出的基本类型


注意:
<1>声明异常的关键字是:throws;  抛出异常的关键字是: throw

<2>一个方法只能抛出在方法声明中声明的异常以及异常Error,RuntimeException和它们的子类。例如;如果没有在方法声明中声明IOException异常,那么在这个方法体中就不能抛出它。但是,即使方法没有声明RuntimeException或它的子类,方法也总能抛出它们。此外,java强迫程序员处理异常。如果一个方法声明了Error和RuntimeException之外的异常,则必须在调用它的地方用try语句中进行捕获和处理,以避免程序突然中止。

 <3>如果try块中的某条语句抛出了一个异常,那么java就会略过其余语句,开始为该异常搜索异常处理器。如果异常的类型与某个catch子句所列的异常匹配,就会执行该catch语句子句中的代码,如果异常类型与任何一个catch子句中的异常都不匹配,那么就会跳过try块中的其它语句,执行finally子句,并退出这个方法,将异常传递给调用该方法的方法,继续重复寻找事件处理器的过程。如果在方法调用链中始终没有找到异常处理器,程序就会中止,并在控制台上打印出错误信息。

 <4>如果在图形程序中出现了Exception子类的一个异常,java在控制台上打印错误,但程序回到处理用户界面的循环继续运行,忽略该异常。

 <5>如果一个catch子句捕获了一个父类的异常,它就能捕获那个父类所有子类的异常对象。

 <6>catch子句中指定异常的顺序非常重要。如果在父类的异常对象前没有指定这个异常对象,就会导致编译错误。
 <7>通常情况下,异常处理需要更多的时间和资源。如果可能的话应该用判断语句测试简单的异常。而用异常去处理那些if语句不能解决的问题。

3.finally语句定义一个总是被执行的代码块,而不管有没有出现异常
-----------------------------
public void work() {
  try{
   开门
   工作8个小时  //可能会抛出DiseaseException异常
  }catch(DiseaseException e){
    去医院看病;
  }finally{
    关门
  }
}
finally语句不被执行的唯一情况是程序先执行了终止程序的System.exit()方法
注意:即使在函数中使用return()语句也不能禁止执行return()语句块
public static void main(String args[]){
  try{
System.out.println("Begin");
return();   //在跳出本函数之前,仍然先执行finally语句块
    System.exit(0);
  }finally{
    System.out.println("Finally");
  }
  System.out.println("End");
}

4.
异常处理流程
try{
  code1;  //可能抛出各种异常
}catch(SQLException e){
  System.out.println("SQLException");
}catch(IOException e){
  System.out.println("IOException");
}catch(Exception e){  //通常将异常继承关系中顶层异常放在最后
  System.out.println("Exception");
}

5.
运行时异常 (不受检查异常)
java并未要求在方法中显示的声明运行时异常,这些异常异常会自动被JVM抛出
RuntimeException类及其子类都称为运行时异常,这种异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过,只会在运行时才报错。例如当以下divide()方法的参数b为0,执行“a/b”操作时会出现ArrithmeticException异常,它属于运行时异常,Java编译器不会检查它:
原因 :RuntimeException代表的是编程异常,这些错误是无法预料。所以不可能交给编译器在编译时做检查
public int divide(int a,int b){
  return a/b;  //当参数b为0,抛出ArrithmeticException
}

区分运行时异常和受检查异常
运行时异常表示无法让程序恢复运行的异常,导致这种异常的原因通常是由于执行了错误操作。一旦出现了错误操作,建议终止程序(会抛出异常并终止程序),因此Java编译器不检查这种异常。


public void method(int[] array){
  for(int i=0;i<=array.length;i++)
    array[i]=1;  //当i的取值为array.length时,将抛出ArrayIndexOutOfBoundsException
}

-------
修改为
public void method(int[] array){
  for(int i=0;i     array[i]=1;  //不会抛出ArrayIndexOutOfBoundsException
}
-------------
受检查异常
表示程序可以处理的异常,如果抛出异常的方法本身不能处理它,那么方法调用者应该去处理它,从而使程序恢复运行,不至于终止程序。
如果一个方法可能出现受检查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出(当然也可以声明抛出它的父类异常),那么就需要在使用该方法的地方捕获异常或再一次将他抛出,否则在编译时就会导致编译错误。

void method1() throws IOException{}  //合法

//编译错误,必须捕获或声明抛出IOException
void method2(){
  method1(); 
}

//合法,声明抛出IOException
void method3()throws IOException {
  method1(); 
}
------------------
//合法,声明抛出Exception
void method4() throws Exception {
  method1(); 
}

//合法,捕获IOException
void method5(){
 try{
    method1(); 
 }catch(IOException e){…}
}
------------------------
用户定义异常
用户定义异常是通过扩展Exception类或RuntimeException来创建的
class AnswerWrongException extends Exception {
    private int result;
    public AnswerWrongException (int result){
      this.result=result;
    }
    public int getResult() {
      return result;
    }
 }
----------------
public class ExceptionTester{
  public static void test(int x,int y,int z)throws AnswerWrongException{
    if(x+y!=z) throw new AnswerWrongException(z);
    System.out.println(x+"+"+y+"="+z);
  }
  public static void main(String args[]) {
    try{
      test(1,2,5);
      System.out.println("end");
    }catch( AnswerWrongException e){
       System.out.println("result is wrong:"+e.getResult());
       e.printStackTrace();
    }
  }
}
------------------

案例分析:
public class Compute {
 /**
  * 方法本身处理异常,调用者就不能再处理
  */
 public int work(int a,int b){
  int result = 0;
  try{
   result = a/b;
  }catch(Exception e){
   e.printStackTrace();
  }
  return result;
 }
 /**
  * 方法本身不做统一的异常处理
  * 由调用者自己进行处理,能满足
  * 调用者想进行不同处理的情况
  */
 public int work1(int a,int b) throws Exception{
  int result = 0;
  result = a/b;
  return result;
 }
 /**
  * 方法本身进行异常的处理
  * 同时调用者也进行各自的处理
  * 需要在方法的catch里处理完后,再
  * throw该异常对象
  */
 public int work2(int a,int b) throws Exception{
  int result = 0;
  try{
   result = a/b;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println("in work2");
   throw e;    //将这个异常抛给方法的调用者再进行处理
  }
  return result;
 }
 /**
  * 使用返回值让调用者判断区分处理
  */
 public int work3(){
  ///
  //
  int a = 12;
  if(a==12){
   return 1;
  }
  System.out.println("in work3");
  return 2;
 }
 /**
  * 使用抛出异常对象来达到让调用者区分
  * 处理的目的
  */
 public void work4() throws Exception{
  int a = 12;
  if(a==12){
   throw new Exception();     //
  }
  System.out.println("in work4");
 }
 
 public void work5() throws RuntimeException{
  int b = 12;
  if(b==12){
   throw new RuntimeException();     //可以起到流程控制的作用
  }
  System.out.println("in work5");
 }
}
/**
 * throws throw
 * 1:使用的位置  throws  放在方法参数的后边
 *              throw 放在方法里面
 * 2:从后面跟的内容   throws   异常的类名
 *                  throw    异常类的对象
 * 3:从功能   throws 表示该方法不处理异常,方法
 *                  产生的异常一定由调用者处理
 *           throw  主动抛出一个异常类的对象
 */

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值