20160723 异常/

来源:互联网 发布:淘宝电器以旧换新 编辑:程序博客网 时间:2024/05/17 01:10

异常:

程序在执行过程中出现不正常的现象

import java.util.Scanner;class ExceptionDemon1 {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt();int num=devide(a,b);//System.out.println("商为: "+num);}<pre name="code" class="java">

//除法计算public static int devide(int a,int b){ return a/b;// }}

/*请输入除数:0请输入被除数:1Exception in thread "main" java.lang.ArithmeticException: / by zero        at ExceptionDemon1.devide(ExceptionDemon1.java:20)        at ExceptionDemon1.main(ExceptionDemon1.java:13)请按任意键继续. . .*/

主方法是怎么处理异常的?

主方法在处理异常时是没有对异常做相关的处理操作,
仅仅是将异常的信息,以及相关的错误代码打印到控制台上

class ExceptionDemon2 {public static void main(String[] args) {int []array={1,4,6,8};for (int i=0;i<array.length ;i++ ){System.out.println(array[i]);}}}

我们应该怎么去处理异常?

      由于异常的信息特别多,我们需要将异常的信息进行封装,
 我们之前学过面向对象,在这里可以采用面向对象的思维去对异常进行封装


 但是异常也分为严重与不严重的情况,通过面向对象的思维模式,可以将异常的这两种情况提取出来进行封装,在java中已经进行了一个体系
 其顶层是Throwable


 Throwable类 是java语言中所有错误和异常的超类


 Throwable
     Error:不在我们处理范围内的异常,属于严重的错误
 Exception:在我们处理范围内的异常,能够通过我们进行处理


       实例1:
    1.我们骑自行车出去玩,自行车的链条坏了----可处理范围内
2.我们骑自行车出去玩,路断了====不在处理范围内


       实例2:
    1.得了感冒----可以买要吃解决
2.得了癌症----吃药是无法解决的,属于严重错误

class ExceptionDemon3 {public static void main(String[] args) {byte [] by=new byte[1000*1024*1024];System.out.println(by); /*Exception in thread "main" java.lang.OutOfMemoryError: Java heap space---内存溢出        at ExceptionDemon3.main(ExceptionDemon3.java:27)*/}}

*Throwable(可抛出;异常;对象)有哪些方法?



  getMessage()--返回此Throwable的详细消息字符串(获取异常信息返回字符串)


  printStackTrace()--将此 throwable 及其追踪输出至标准错误流。(获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void)


  printStackTrace(PrintStream s)--将此 throwable 及其追踪输出到指定的输出流。 (通常用该方法将异常内容保存在日志文件中,以便查阅)
                                 字节流
  printStackTrace(PrintWriter s)--将此 throwable 及其追踪输出到指定的 PrintWriter                                                 "自己去试"
                                  字符流


  toString()--返回此 throwable 的简短描述(获取异常类名和异常信息,返回字符串)


**自己怎么处理异常?
  1.try(发现异常)--catch(处理异常)  finally(处理)  catch是必带的,仅仅try是不可以的


    a.try...catch             一发现一处理
b.try...catch...catch...  一发现多处理(无限多)


**原则:先处理小的,再处理大的

import java.util.Scanner;import java.lang.ArithmeticException;import java.lang.ArrayIndexOutOfBoundsException;//导入异常class  ExceptionDemon4{public static void main(String[] args) {           //扫描控制台输入/*Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt();*/        /*   try//发现异常           //---      {      int num=devide(a,b);//              System.out.println("商为: "+num);  int[]array={1,3};  System.out.println(array[2]);//取不到              }     */        /*  catch(ArithmeticException e)                   //-----   {                 System.out.println("报错了");       }   catch(ArrayIndexOutOfBoundsException e)                 //-----   {                 System.out.println("数组脚标越界");       }*/        /*                Exception in thread "main" java.lang.ArithmeticException: / by zero                at ExceptionDemon1.devide(ExceptionDemon1.java:20)                at ExceptionDemon1.main(ExceptionDemon1.java:13)       */   try   {int[]array={1,3};System.out.println(array[2]);//                         -   }   catch (Exception e)//catch它的父类,下面任何子类报出来的时候,我们都能捕捉到//超级父类Throwable也可以,但一般会这么做,因为会包含Error的错误,Error也捕捉不到                                                                                    {   System.out.println("报错了");     // String message=e.getMessage();//获取异常信息返回字符串  // System.out.println(message);//2 // e.printStackTrace();//不返回什么,直接打印到控制台(获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void)                      //报错了                                      //java.lang.ArrayIndexOutOfBoundsException: 2--①                                      //at ExceptionDemon4.main(ExceptionDemon4.java:71)                 System.out.println(e.toString());//(获取异常类名和异常信息,返回字符串)                                  //java.lang.ArrayIndexOutOfBoundsException: 2--①   }   System.out.println("******结束******");//正常打印                                                  /*                Exception in thread "main" java.lang.ArithmeticException: / by zero                at ExceptionDemon1.devide(ExceptionDemon1.java:20)                at ExceptionDemon1.main(ExceptionDemon1.java:13)       */}    //除法计算public static int devide(int a,int b){ return a/b;//    }    }
**①原则:先处理小的,再处理大的


         ②try处理的优先级问题


③try 和 finally 配合问题
  a.
  b.
  c.try...catch...finally(里面的内容为-无论是否异常-必须执行!)
             放在finally里执行的内容一般为:资源必须关闭等操作
           d.try..catch...catch... finally
  e.try...finally
  
  ④为什么不报错的代码我们不一起放到try中?
     (try中要报错的系统会预分配内存)
放在try中的内容,在执行过程中java虚拟机会进行分配相应的空间
如果把没有报异常的代码一并放入try中,会降低程序的执行效率,所以通常不报错的代码不放在try中
*/
import java.util.Scanner;import java.lang.ArithmeticException;import java.lang.ArrayIndexOutOfBoundsException;//导入异常class  ExceptionDemon5{public static void main(String[] args) {           //扫描控制台输入Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt();     /*      try//发现异常         //---      {      int num=devide(a,b);//              System.out.println("商为: "+num);  //int[]array={1,3};  //System.out.println(array[2]);//取不到              } */           /*  catch(ArithmeticException e)         //-----   {                 System.out.println("报错了");       }   catch(ArrayIndexOutOfBoundsException e)         //-----   {                 System.out.println("数组脚标越界");       }     catch(Exception e)         //-----   {                 System.out.println("展现的是父类异常");       }*/System.out.println("------------------分隔符----------------------");/*       try//发现异常         //---      {      int num=devide(a,b);//              System.out.println("商为: "+num);  int[]array={1,3};  System.out.println(array[2]);//取不到              }              catch(ArrayIndexOutOfBoundsException e)         //-----   {                 System.out.println("数组脚标越界");       }     catch(Exception e)         //-----   {                 System.out.println("展现的是父类异常");       }   finally    {    System.out.println("最终执行,必须执行我");       }*/System.out.println("------------------分隔符1----------------------");         /*          try//发现异常         //---      {      int[]array={1,3};  System.out.println(array[2]);//取不到              }              catch(ArrayIndexOutOfBoundsException e)         //-----   {                 System.out.println("数组脚标越界");       }   finally    {    System.out.println("最终执行,必须执行我1");       }          try//发现异常         //---      {      int num=devide(a,b);//              System.out.println("商为: "+num);             }         catch(Exception e)         //-----   {                 System.out.println("展现的是父类异常");       }   finally    {    System.out.println("最终执行,必须执行我2");       }*/System.out.println("------------------分隔符2----------------------");  //System.exit(0);//相当于是程序式的直接中断,之下的内容就不会被执行    try//发现异常         //---      {      int num=devide(a,b);//              System.out.println("商为: "+num);              System.exit(0);//放在这里也可以,无异常时,num输出,finally也不会被执行,没有"结束"                   //但是异常时,直接跳到finally执行,输出printStackTrace(),没有"结束"             }    finally    {    System.out.println("最终执行,必须执行我2");       }//异常的话,执行依然报错,所以没有"结束"System.out.println("******结束******");//正常打印}    //除法计算public static int devide(int a,int b){ return a/b;//    }    }

异常的第二种处理方式:

      自己不处理该异常,将该异常[抛出,谁调用谁处理
 抛异常的关键字是throws


*主函数调用了这个异常,主函数两种处理方式
 ①try..catch 处理掉
 ②直接抛掉不再处理(不处理,谁调用谁处理)


*处理异常的两种方式到底哪一种好?
 原则:能处理则处理,处理不好则抛出
class  ExceptionDemon6{public static void main(String[] args) throws Exception//下边也不想处理了,直接交给java虚拟机处理---②{//int num=devide(10,2);---零//System.out.println(num);//5        //int num=devide(10,0);---零//System.out.println(num);//不能除以0                        //0        //int num=devide(10,1);---②//System.out.println(num);//10        int num=devide(10,0);//---②System.out.println(num);//报异常,printStackTrace()类型     /*   try                        //---①        {int num=devide(10,0);System.out.println(num);        }        catch (Exception e)        {System.out.println("不能除以0");//输出"不能除以0"        }*/  /*  try                           //---①        {int num=devide(10,1);System.out.println(num);        }        catch (Exception e)        {System.out.println("不能除以0");//输出="10"        }*/}/*public static int devide(int a,int b)--零{ int result=0; try {result=a/b; } catch (ArithmeticException e) { System.out.println("不能除以0"); } return result;    }*///System.out.println("----------分隔符-------------");       public static int devide(int a,int b)throws Exception//---①,②   //ExceptionDemon6.java:13: 错误: 未报告的异常错误Exception; 必须对其进行捕获或声明以便抛出{ /*int result=0; try {result=a/b; } catch (ArithmeticException e) { System.out.println("不能除以0"); } return result;*/ return a/b;    }}

throws 和throw



  throws用于标识函数暴露出的异常
  throw用于抛出异常对象


  *区别:
   1. throws用在函数上,后面跟"异常类名"
   throw用在函数内,后面跟"异常对象"


   2.throws可以单独使用
   throw必须与throws组合使用(RuntimeException)




   处理异常:①抛给java虚拟机②try...catch


            还有一种:直接抛掉,不想交给谁去处理


     **RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类,
可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明。//--在大数据运用中缩短排查错的时间
                                                                                                 今后会教怎么用这种方式去排查错误,缩短查找时间


   RuntimeException与Exception的区别:
         1.Exception是编译时会检测的异常,是需要编写代码进行处理的
2.RuntimeException是运行时的异常,在编译过程中不检测
        
*/
class  ExceptionDemon7{/*public static void main(String[] args) throws Exception          //--调用的是throws{        int num=devide(10,0);System.out.println(num);     }       public static int devide(int a,int b)throws Exception { return a/b;    }*/      //----------------------------------------------------------------------------------------    /*      public static void main(String[] args) throws Exception  {        int num=devide(10,0);System.out.println(num);//10(非异常)     }       public static int devide(int a,int b) throws Exception{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0" } return result;    }*///------------------------------------------------------------------------------------     /*       public static void main(String[] args) {  try                                {int num=devide(10,0);System.out.println(num);//10(非异常)        }        catch (Exception e)        {System.out.println("不能除以0");//输出"不能除以0"(异常)        }        //int num=devide(10,1);//System.out.println(num);     }       public static int devide(int a,int b) throws Exception{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数 } return result;    }*///---------------------------------------------------------------------/*       public static void main(String[] args) throws Exception{//  try                                // {//int num=devide(10,0);//System.out.println(num);//10(非异常)        //  }        // catch (Exception e)        // {//System.out.println("不能除以0");//输出"不能除以0"(异常)        //  }        int num=devide(10,0);System.out.println(num);     }       public static int devide(int a,int b) throws Exception//                                                  ---------//                                                  到时候抛的不是这个异常,而是其他异常,从114行抛出时,可以有效的帮助我们在前面的代码中查找错误{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0"                                  //可以帮我们达到异常的转换目的 } return result;    }*///--------------------------------------------------------------------------------------------------------------- public static void main(String[] args) //不抛--------------抛出的是RuntimeException的时候,主函数中谁调用都不需再处理,                                       //                  也不需要再进行一个声明{/*  try                                {int num=devide(10,0);System.out.println(num);//10(非异常)        }        catch (Exception e)        {System.out.println("不能除以0");//输出"不能除以0"(异常)        }*/        int num=devide(10,0);System.out.println(num);     }       public static int devide(int a,int b) //不抛{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new RuntimeException("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0"                                  //可以帮我们达到异常的转换目的 } return result;                               }                                     //输出为:Exception in thread "main" java.lang.RuntimeException: 不能除以0                                          //at ExceptionDemon7.devide(ExceptionDemon7.java:154)                                          //at ExceptionDemon7.main(ExceptionDemon7.java:140)}

finalize 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
            子类重写 finalize 方法,以配置系统资源或执行其他清除。


    final finally finalize三者之间的区别?
final:可以有来修饰类,成员变量,成员方法;如果用来修饰类,则此类不能被继承
     如果用来修饰成员变量,则此变量不能被改变,如果用来修饰成员方法,
 则此方法不能被重写
    finally:属于是异常体系中的一个关键词,一般用于释放资源,永远被执行
       但特殊情况System.exit(0)除外
    finalize:是Object类中的一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象
        的垃圾回收器调用此方法

class  FinallyDemon8{public static void main(String[] args) {int final String line="测试";//          -----try{int value=devide(a,b);System.out.println("商为:"+value);}finally (){System.out.println("必须执行我");}}    //除法计算public static int devide(int a,int b){ return a/b;    }}

/*

  总结:

   Exception异常体系在继承中的表现情况?
     a.在继承过程中,子类继承方法不能抛比父类中更多更大的异常
b.但可以抛父类中异常的子类异常或是相同的异常,一般是直接抛和父类中相同的异常

*/

/*class Demon
{
public static void printTest()throws ClassNotFoundException
{
System.out.println("调用我会抛异常");//方法抛出了一个异常-----①
                                    //ExtendDemon9.java:12: 错误: 未报告的异常错误ClassNotFoundException; 必须对其进行捕获或声明以便抛出
   }
}
class ExtendDemon9 extends Demon
{
public static void main(String[] args) throws Exception//加上(抛出最大的异常)此句后,输出①
//                                       ----------------
{
printTest();
}
}*/


//-----------------------------------------------------------


/*
  第二项中
   a.throws NotBoundException--ExtendDemon9.java:36: 错误: 找不到符号
   b.throws Exception---ExtendDemon9.java:44: 错误: ExtendDemon9中的printTest()无法覆盖Demon中的printTest()
  
 ** 在子类中不能抛比①中异常还大的异常,可以抛比它小的异常吗?
*/
/*class Demon
{
public static void printTest()throws ClassNotFoundException//--①
{
System.out.println("调用我会抛异常");
   }
}
class ExtendDemon9 extends Demon
{
public static void main(String[] args) throws Exception


{
printTest();
}


public static void printTest()                         //throws NotBoundException与throws Exception//都拋不过去  
//                                ------------------------
{
System.out.println("我是子类");//重写之后,输出"我是子类"
   }
}*/


//*************************************************************************************


//** 在子类中(②)不能抛比①中异常还大的异常,可以抛比它小的异常吗?(①与②的抛出交换)
//                                      A:  只能是相同或是父类中异常的子类  (绝对不能抛上面"没有"的异常)


class Demon{public static void printTest()throws Exception//--①{System.out.println("调用我会抛异常");    }}class ExtendDemon9 extends Demon{public static void main(String[] args) throws Exception{printTest();}public static void printTest()throws ClassNotFoundException//--②//                                {System.out.println("我是子类");//输出:我是子类    }}
/*  Q1:为什么要采用自定义异常?(有了java体系定义的那一套异常,为什么还要自定义)  A1:因为java定义的异常是常用的异常,根据我们的业务需求,是无法全部满足的    所以需要自定义异常  Q2;怎么定义自定义异常?  A2:继承Exception或RuntimeException(抛了后者这个异常,不需要在编写代码中做任何处理,但一般很少用这个异常,一般处理一些特殊跟踪异常才会用到)根据自己的需求,报什么异常,为了跟踪什么错误,然后我们就自己直接自定义异常*//*class MyException extends Exception{private int  number;public MyException(String message,int number){ super(message); this.number=number;    }    public int getNumber(){ return number;    }}class Demon{public void devide(int a,int b) throws MyException//如果没这个抛出,则ExceptionDemon10.java:30: 错误: 未报告的异常错误MyException; 必须对其进行捕获或声明以便抛出{           if (b<0)           {   throw new MyException("除数不能为0",b);           }   else   {                 System.out.println("商为:"+a/b);       }    }}class ExceptionDemon10{public static void main(String[] args) {Demon demon=new Demon();demon.devide(2,3);//ExceptionDemon10.java:44: 错误: 无法将类 Demon中的方法 devide应用到给定类型;                  //加上"2,3"后,ExceptionDemon10.java:44: 错误: 未报告的异常错误MyException; 必须对其进行捕获或声明以便抛出}}*///------------------------------------------------------------------------------------------------/*class MyException extends Exception//------------------这里是自定义的异常{private int  number;public MyException(String message,int number){ super(message); this.number=number;    }    public int getNumber(){ return number;    }}*/class MyRuntimeException extends RuntimeException{        public MyRuntimeException(String message){ super(message);     }}/*class Demon{public void devide(int a,int b) throws MyException{           if (b==0)           {   throw new MyException("除数不能为0",b);//抛出了"除数不能为零"+0           }   else   {                 System.out.println("商为:"+a/b);       }    }}*/class Demon1{public void devide(int a,int b)throws MyRuntimeException{ if (b==0) { throw new MyRuntimeException("除数不能为零");//多了",b",//ExceptionDemon10.java:98: 错误: 无法将类 MyRuntimeException中的构造器 MyRuntimeException应用到给定类型; } else  {  System.out.println("商为:"+a/b);     }    }}class ExceptionDemon10{public static void main(String[] args) //throws MyException//此处相对于上为新增加--不抛,因为要打印异常信息{/*try{Demon demon=new Demon();    //demon.devide(4,2);//商为:2            demon.devide(4,-0);//0----除数不能为0//demon.devide(4,-2);//商为:-2}catch (MyException e){System.out.println(e.getNumber()+"----"+e.getMessage());}*/Demon1 demon1=new Demon1();//上面的已经抛了,这里不需要再做声明了//demon1.devide(6,1);//6demon1.devide(6,0);//Exception in thread "main" MyRuntimeException: 除数不能为零                       //at Demon1.devide(ExceptionDemon10.java:98)                       //at ExceptionDemon10.main(ExceptionDemon10.java:126)   //以上为直接交给java虚拟机进行的处理}}



0 0
原创粉丝点击