• Java基础_学习笔记_14_异常


     1 class Test
     2 {
     3     public int devide(int x,int y)
     4     {
     5         int result=x/y;
     6         return result;
     7     }
     8 }
     9 class TestException
    10 {
    11     public static void main(String [] args)
    12     {
    13         Test t=new Test();
    14         t.devide(2,0);
    15         System.out.println("the program is running here!");
    16     }
    17 }
    18 /*
    19 F:java_examplelesson61>java TestException
    20 Exception in thread "main" java.lang.ArithmeticException: / by zero
    21         at Test.devide(Test.java:5)
    22         at TestException.main(Test.java:14)
    23 */
    View Code

    上述代码中,由于除数为零,导致程序崩溃,后面的代码都不能执行。在实际工作中,或多或少会有各种异常出现,为了尽量避免,需要引入异常的处理机制。

    经过异常处理之后,代码如下

     1 class Test
     2 {
     3     public int divide(int x,int y)
     4     {
     5         int result=x/y;
     6         return result;
     7     }
     8 }
     9 class TestException
    10 {
    11     public static void main(String [] args)
    12     {
    13         Test t=new Test();
    14         try{
    15             t.divide(2,0);
             System.out.println("the divide opration is over");
    16 } 17 catch(Exception e) 18 { 19 System.out.println(e.getMessage()); 20 } 21 System.out.println("the program is running here!"); 22 } 23 } 24 /* 25 F:java_examplelesson61>java TestException 26 / by zero 27 the program is running here! 28 */

    在上述代码中,try的部分写入可能会发生异常的代码,异常发生后会直接转向执行catch部分代码,try中异常语句后面的代码会被忽略,如程序中的System.out.println("the devide operation is over!");语句不会被执行。整个执行流程是当try中的语句发生异常,程序会调用catch,执行完catch中的程序之后,系统会继续执行catch代码块后的其他代码。

    当try代码块中的程序发生异常,系统将这个异常发生的代码行号、类别等信息封装到一个对象中,并将该对象传递给catch代码块。catch关键字后跟有一个Exception类型的参数e,这跟我们经常用到的,如何定义一个函数接收的参数格式是一样的。括号中的Exception就是try代码块传递给catch代码块的变量类型,e是变量名,也可以换成别的名称。

    如果我们将catch中不写任何语句,是空的,那么当try中代码发生异常后,不会打印出任何异常信息,而很难让人觉察到程序的错误,所以这一步不能偷懒。

    throws关键字

    在实际工作中,代码不止是一个人编写的,前一个人编写了一个函数,另一个人需要调用,如果这个函数在调用过程中会发生异常,但是后面的人不知道,那么一场就很可能会发生并导致程序崩溃,那么我们就引入了throws关键字。写devide方法的人需要在定义该方法时加上throws 关键字,调用者在调用该方法时,加上try...catch语句进行处理。若只用throws声明,哪怕函数是正确被调用,没有写try...catch则程序编译无法通过,如下:

     1 class Test
     2 {
     3     public int divide(int x,int y) throws Exception
     4     {
     5         int result=x/y;
     6         return result;
     7     }
     8 }
     9 class TestException
    10 {
    11     public static void main(String [] args)
    12     {
    13         Test t=new Test();
    14         //try{
    15             t.divide(2,1);
    16             System.out.println("the divide opration is over");
    17         //}
    18         /*catch(Exception e)
    19         {
    20             System.out.println(e.getMessage());
    21         }*/
    22         System.out.println("the program is running here!");
    23     }
    24 }
    25 /*
    26 F:java_examplelesson61>javac Test.java
    27 Test.java:15: 错误: 未报告的异常错误Exception; 必须对其进行捕获或声明以便抛出
    28                         t.devide(2,1);
    29                                 ^
    30 1 个错误
    31 */

    将注释去掉之后,程序即可运行成功。

    自定义异常与throw关键字

    Exception类是java.lang.Throwable类的子类,Exception类继承了Throwable类的所有方法,在实际应用中,是使用Exception的子类来描述任何特定的异常。Exception类是所有异常类的父类,java中提供了常见的异常,比如:

    ArithmeticException 在算术运算中发生的异常,如除数为零;

    NullPointerException 空指针异常

    ArrayIndexOutOfBoundsException 访问数组对象中存在的元素

    除了系统定义的异常,我们也可以自己定义异常类,自定义的异常类必须继承Exception类

     1 class Test
     2 {
     3     public int devide(int x,int y) throws Exception
     4     {
     5         if(y<0)
     6             throw new DevideByMinusException("the divisor is negative "+y);
     7         //这里抛出的异常对象,就是catch(Exception e)中的e
     8         int result=x/y;
     9         return result;
    10     }
    11 }
    12 class DevideByMinusException extends Exception
    13 {
    14     public DevideByMinusException(String msg)
    15     {
    16         super(msg);
    17     }
    18 }
    19 class TestException
    20 {
    21     public static void main(String [] args)
    22     {
    23         Test t=new Test();
    24         try{
    25             t.devide(2,-1);
    26             System.out.println("the devide opration is over");
    27         }
    28         catch(Exception e)
    29         {
    30             System.out.println(e.getMessage());//打印出the divisor is negative -1
    31             e.printStackTrace();
    32         }
    33         System.out.println("the program is running here!");
    34     }
    35 }
    36 /*
    37 F:java_examplelesson61>java TestException
    38 the divisor is negative -1
    39 DevideByMinusException: the divisor is negative -1
    40         at Test.devide(Test.java:6)
    41         at TestException.main(Test.java:25)
    42 the program is running here!
    43 */
    View Code

    java通过throw关键字抛出异常对象,语法格式是:

    throw 异常对象;

    一个try后面可以有多个catch,try中语句出现了哪种异常,就去执行对应的catch

     1 class Test
     2 {
     3     public int divide(int x,int y) throws ArithmeticException,DivideByMinusException
     4     {
     5         if(y<0)
     6             throw new DivideByMinusException("the divisor is negative "+y);
     7         //这里抛出的异常对象,就是catch(Exception e)中的e
     8         int result=x/y;
     9         return result;
    10     }
    11 }
    12 class DivideByMinusException extends Exception
    13 {
    14     public DivideByMinusException(String msg)
    15     {
    16         super(msg);
    17     }
    18 }
    19 class TestException
    20 {
    21     public static void main(String [] args)
    22     {
    23         Test t=new Test();
    24         try{
    25             t.divide(2,1);
    26             System.out.println("the divide opration is over");
    27         }
    28         catch(ArithmeticException e)
    29         {
    30             System.out.println("Error ~ ArithmeticException");
    31             e.printStackTrace();//Exception类中的方法
    32         }
    33         catch(DivideByMinusException e)
    34         {
    35             System.out.println("Error ~ DivideByMinusException");
    36             e.printStackTrace();
    37         }
    38         catch(Exception e)
    39         {
    40             System.out.println(e.getMessage());//打印出the divisor is negative -1
    41             e.printStackTrace();
    42         }
    43         System.out.println("the program is running here!");
    44     }
    45 }
    46 /*
    47 F:java_examplelesson61>java TestException
    48 Error ~ DivideByMinusException
    49 DivideByMinusException: the divisor is negative -1
    50         at Test.divide(Test.java:6)
    51         at TestException.main(Test.java:25)
    52 the program is running here!
    53 */
    View Code

    上述代码,若没有发生异常就不进入任何catch,如果try中语句发生了异常,且该异常没有对应的catch,那么它就会执行Exception的catch,也就是我们代码中最后一个catch,因为所有的异常都是Exception的子类。也正因为如此,我们Exception对应的catch只能放在最后,如果不是放在最后,则程序编译错误,如下所示

     1 class Test
     2 {
     3     public int divide(int x,int y) throws ArithmeticException,DivideByMinusException
     4     {
     5         if(y<0)
     6             throw new DivideByMinusException("the divisor is negative "+y);
     7         //这里抛出的异常对象,就是catch(Exception e)中的e
     8         int result=x/y;
     9         return result;
    10     }
    11 }
    12 class DivideByMinusException extends Exception
    13 {
    14     public DivideByMinusException(String msg)
    15     {
    16         super(msg);
    17     }
    18 }
    19 class TestException
    20 {
    21     public static void main(String [] args)
    22     {
    23         Test t=new Test();
    24         try{
    25             t.divide(2,1);
    26             System.out.println("the divide opration is over");
    27         }
    28         catch(Exception e)
    29         {
    30             System.out.println(e.getMessage());//打印出the divisor is negative -1
    31             e.printStackTrace();
    32         }
    33         catch(ArithmeticException e)
    34         {
    35             System.out.println("Error ~ ArithmeticException");
    36             e.printStackTrace();//Exception类中的方法
    37         }
    38         
    39         catch(DivideByMinusException e)
    40         {
    41             System.out.println("Error ~ DivideByMinusException");
    42             e.printStackTrace();
    43         }
    44         /*catch(Exception e)
    45         {
    46             System.out.println(e.getMessage());//打印出the divisor is negative -1
    47             e.printStackTrace();
    48         }*/
    49         System.out.println("the program is running here!");
    50     }
    51 }
    52 /*
    53 F:java_examplelesson61>javac Test.java
    54 Test.java:33: 错误: 已捕获到异常错误ArithmeticException
    55                 catch(ArithmeticException e)
    56                 ^
    57 Test.java:39: 错误: 已捕获到异常错误DivideByMinusException
    58                 catch(DivideByMinusException e)
    59                 ^
    60 2 个错误
    61 */
    View Code

    在实际应用中,我们可以通过try...catch来实现程序的跳转,下面例子中并不是真的有异常,而是我们利用try...catch的特点实现跳转

     1 void fun
     2 {
     3     try{
     4         if (x==0)
     5             throw new XxxException("Xxx");
     6         else
     7             throw new YyyException("Yyy");
     8     }
     9     catch(XxxException e)
    10     {...}
    11     catch(YyyException e)
    12     {...}
    13 }
    View Code

    finally关键字

    使用这个关键字,在一般情况下不管程序是跳转到了哪种异常或者是没有异常,都会去执行finally中的代码块。那么问题来了,我catch后面的最后一个输出语句,也是不论有没有异常也会执行啊,何必要用一个finally呢?下面我们来看区别

     1 class Test
     2 {
     3     public int divide(int x,int y) throws ArithmeticException,DivideByMinusException
     4     {
     5         if(y<0)
     6             throw new DivideByMinusException("the divisor is negative "+y);
     7         //这里抛出的异常对象,就是catch(Exception e)中的e
     8         int result=x/y;
     9         return result;
    10     }
    11 }
    12 class DivideByMinusException extends Exception
    13 {
    14     public DivideByMinusException(String msg)
    15     {
    16         super(msg);
    17     }
    18 }
    19 class TestException
    20 {
    21     public static void main(String [] args)
    22     {
    23         Test t=new Test();
    24         try{
    25             t.divide(2,-1);
    26             System.out.println("the divide opration is over");
    27         }
    28         catch(ArithmeticException e)
    29         {
    30             System.out.println("Error ~ ArithmeticException");
    31             e.printStackTrace();//Exception类中的方法
    32         }
    33         
    34         catch(DivideByMinusException e)
    35         {
    36             System.out.println("Error ~ DivideByMinusException");
    37             e.printStackTrace();
    38             return;//结束函数,有返回值的返回值,所以不会打印出B
    39             //System.exit(0);//表示程序到此终止
    40         }
    41         catch(Exception e)
    42         {
    43             System.out.println(e.getMessage());//打印出the divisor is negative -1
    44             e.printStackTrace();
    45         }
    46         finally
    47         {
    48             System.out.println("finally~");//A语句
    49         }
    50         System.out.println("the program is running here!");//B语句
    51     }
    52 }
    53 /*
    54 F:java_examplelesson61>java TestException
    55 Error ~ DivideByMinusException
    56 DivideByMinusException: the divisor is negative -1
    57         at Test.divide(Test.java:6)
    58         at TestException.main(Test.java:25)
    59 finally~
    60 */
    View Code

    加了return之后,没有执行B,但执行了A,说明不管函数有没有返回,finally部分都是要执行的。只有一种情况下,finally不会被执行,就是加了System.exit(0),表明程序到此结束。

    注意:当类中方法有进行异常处理,那其子类若覆盖该方法要么不进行异常处理,要么子类中异常是父类异常的子集。

    引入异常机制,可以加强程序的安全性、强健性。

  • 相关阅读:
    android学习-仿Wifi模块实现
    爬虫4:cookie登陆并爬取学习成绩
    爬虫3:表单登陆
    爬虫2:爬取百度贴吧的帖子
    爬虫1:爬虫爬取糗事百科
    js中的typeof 操作符
    基于 Token 的身份验证方法
    Jfinal 列表分页
    百度地图逆地址解析
    Jfinal 项目搭建
  • 原文地址:https://www.cnblogs.com/tiantianxiangshang33/p/4957683.html
Copyright © 2020-2023  润新知