java 学习笔记(9) Exception Handling

                            Exception Handling

目录:

1. try - catch

   1.1 针对catch(Exception e) 的说明

   1.2 两种情况

   1.3 举例 InputMismatchException

   1.4 throw 

        1.4.1 throw 的介绍

        1.4.2 The getMessage Method

2.  Exception class

3.  Throwing Exception in methods

     3.1 函数和继承

     3.2 继承和异常。

     3.3 Checked and Unchecked Exceptions

1. try - catch

执行方法:我们把可能出现问题的代码放在try中,如果代码在执行的过程当中确实出现了问题。那么try模块儿会停止代码的执行。

                                               

如果相应的catch模块接收到了该抛出的问题。那么会进入到catch模块进行执行。因此每一个,catch模块儿都有一个参数值。只有满足该参数值才能被接收到。该模块中的代码,只有try模块 抛出一个异常的时候才会有执行的可能。并且每个catch中存放的内容都是针对的出现的这个异常的解决办法,是终止程序还是输出等等。 

                                              

1.1 针对catch(Exception e) 的说明

1. Exception部分一定是一个具体的异常的类型,也就是这个catch模块可以处理的异常的类型。如果这个参数位置仍写成Exception,那么他可以处理任何异常。

2.e表示抛出的这个异常的名字,我们可以不使用冗长的名字,一般使用e代替。

 

1.2 两种情况

1. 当没有异常被抛出时,try模块内的代码会被全部执行完毕。catch模块儿的代码会被跳过。继续执行catch模块后面的内容。

2.如果存在异常,并且被抛出后,被相应的catch接收。那么抛出异常的try模块儿后面的代码会被忽略。相应catch中的代码会被执行。一般情况下,由于超出异常后try剩余部分的代码不会被执行。即使有了catch模块,也只是为了不让程序报错正常运行。因此我们一般把try-catch模块儿中的内容,放在loop中。形如:

                              

 

1.3 举例 InputMismatchException

比如期望从用户的键盘输入一个int类型的值。如果用户输入的内容不符合int类型的值。在没有try-catch机制下程序会报错。然后中止执行。但是如果我们一旦有了try-catch机制,就可以针对用户错误的输入进行处理。比如让用户再输入一次。

比如,InputMismatchException异常存在在 java的 java.util 包中。如果想使用该异常,需要对包进行引入。比如:import java.util.InputMismatchException;

1 import java.util.Scanner;
2 import java.util.InputMismatchException;
3 public class InputMismatchExceptionDemo
4 {
5     public static void main(String[] args)
6     {
7         Scanner keyboard = new Scanner(System.in);
8         int number = 0; //to keep compiler happy
9         boolean done = false;
10        while (!done)
11        {
12             try
13            {
14                System.out.println("Enter a whole number:");
15                 number = keyboard.nextInt();
16                 done = true;
17            }
18             catch(InputMismatchException e)
19            {
20                 keyboard.nextLine();
21                 System.out.println("Not a correctly written whole number.");
22                 System.out.println("Try again.");
23            }
24         }
25         System.out.println("You entered " + number);
26     }
27 }

输出结果为

                      

 

1.4 throw 

1.4.1 throw 的介绍

我们刚刚一直谈的抛出异常。并没有显示的对异常进行抛出的动作。如果我们想显示的抛出一个异常,这时这个异常的类型可以是我们自定义的,使用如下的语句

throw new Exception(String_describing _the_exception);

举例中,throw new Exception("Lesson is canceled. No students."); throw new Exception("Lesson is canceled. No men."); throw new Exception("Lesson is canceled. No women.");都是异常的抛出。

try
{
    if (men == 0 && women == 0)
            throw new Exception("Lesson is canceled. No students.");
    else if (men == 0)
            throw new Exception("Lesson is canceled. No men.");
    else if (women == 0)
            throw new Exception("Lesson is canceled. No women.");
     
     // women >= 0 && men >= 0
    if (women >= men)
        System.out.println("Each man must dance with " + women/(double)men + "women.");
    else
        System.out.println("Each woman must dance with " + men/(double)women + " men.");
}


1.4.2 The getMessage Method

该函数的作用是获得抛出异常中异常的信息。一般用于显示。

比如,

throw new Exception("Input must be positive.");

catch (Exception e)
{
     System.out.println(e.getMessage());
     System.out.println("Program aborted.");
     System.exit(0);
}

获得的结果是:"Input must be positive."

--------------------------------------------------------------------------------------------------------------------

2.  Exception class

除了使用java预先为我们设定好的异常类型。我们也可以自定义所需的异常类型。

这是我们需要定义一个类。把这个类的类名命名为异常类型的名字。同时该类必须继承Exception 。同时继承其中的方法getMessage()。一般在自定义的异常类中,我们可以使用无参的构造函数。或者自定义一个构造函数,其中的内容设定为,super("对异常的解释");

比如自定义的异常类为DivisionByZeroException 

1 public class DivisionByZeroException extends Exception
2 {
3     public DivisionByZeroException()
4     {
5         super("Division by Zero!");
6     }
7     public DivisionByZeroException(String message)
8     {
9         super(message);
10    }
11 }

   测试程序为

1 import java.util.Scanner;
2 public class DivisionDemoFirstVersion
3 {
4     public static void main(String[] args)
5    {
6         try
7        {
8             Scanner keyboard = new Scanner(System.in);
9             System.out.println("Enter numerator:");
10            int numerator = keyboard.nextInt();
11            System.out.println("Enter denominator:");
12            int denominator = keyboard.nextInt();
13            if (denominator == 0)
14                 throw new DivisionByZeroException();
15            double quotient = numerator/(double)denominator;
16            System.out.println(numerator + "/"
17                 + denominator
18                 + " = " + quotient);
19        }
20         catch (DivisionByZeroException e)
21        {
22             System.out.println(e.getMessage());
23             secondChance();
24        }
25         System.out.println("End of program.");
26    }

--------------------------------------------------------------------------------------------------------------------

在这里我们说明一下多个catch模块儿的问题。

首先,允许我们有多个模块儿。这样也就可以处理多种异常的情况。但是在编写该模块儿的时候要注意。异常会从上到下依次匹配这些模块儿。也就意味着,具体类型的异常类型应该写在前面。抽象类型的异常类型应该写在后面。

比如,下面的写法就是正确的。如果两个模块儿的参数内容颠倒,就会造成。后面的异常无法被识别。因为,Exception可以接收任何异常。

catch(NegativeNumberException e)
{
.
.
.
}
catch(Exception e)
{
.
.
.

--------------------------------------------------------------------------------------------------------------------

3.  Throwing Exception in methods

3.1 函数和继承

我们之前提到的try-catch模块儿只是一个简单的应用。现在我们来讨论。他如何在一个方法中使用。

首先,当我们抛出一个异常时并不一定要去catch它。需要看具体的需求。

我们可以观察到在主函数中,并没有异常的抛出。但是在第13行。调用了一个函数safeDivide。该函数的heading处,也就是第27,28行,有一个throw 异常抛出的说明。同时我们发现,在函数safeDivide的方法体中,并没有对抛出的异常进行catch,而是在主函数中catch的。

在编程当中这种方式较为常见。虽然我们没有在函数中对抛出的异常进行接收和处理。但是我们同样需要警告该函数。在接下来执行的方法体中可能存在异常抛出的现象。所以我们需要在函数的heading处声明一个异常(declaring the exception),我们称之为throws clause。也就是在27.28行看到的代码

public void sampleMethod() throws DivisionByZeroException

当可能抛出多个异常的时候,我们可以 像下面的这种声明方式进行声明即可。

public void sampleMethod()
                              throws DivisionByZeroException, SomeOtherException

但是值得注意的是,虽然这个函数没有处理异常。只是,对可能抛出的异常进行了显示说明。那么调用该函数的函数。就必须处理他将会抛出的异常。

1 import java.util.Scanner;
2 public class DivisionDemoSecondVersion
3 {
4     public static void main(String[] args)
5     {
6         Scanner keyboard = new Scanner(System.in);
7         try
8        {
9             System.out.println("Enter numerator:");
10             int numerator = keyboard.nextInt();
11             System.out.println("Enter denominator:");
12             int denominator = keyboard.nextInt();
13             double quotient = safeDivide(numerator, denominator);
14             System.out.println(numerator + "/"
15                     + denominator
16                     + " = " + quotient);
17        }
18         catch (DivisionByZeroException e)
19        {
20             System.out.println(e.getMessage());
21             secondChance();
22         }
23
24         System.out.println("End of program.");
25      }
26
27     public static double safeDivide(int top, int bottom)
28                     throws DivisionByZeroException
29     {
30         if (bottom == 0)
31             throw new DivisionByZeroException();
32         return top/(double)bottom;
33     }

34     public static void secondChance()
35     {
36         Scanner keyboard = new Scanner(System.in);
37
38         try
39        {
40             System.out.println("Enter numerator:");
41             int numerator = keyboard.nextInt();
42             System.out.println("Enter denominator:");
43             int denominator = keyboard.nextInt();
44             double quotient = safeDivide(numerator, denominator);
45             System.out.println(numerator + "/"
46                     + denominator
47                     + " = " + quotient);
48        }
49         catch(DivisionByZeroException e)
50        {
51             System.out.println("I cannot do division by zero.");
52             System.out.println("Aborting program.");
53             System.exit(0);
54         }
55     }
56 }

一般情况下,函数只是表示要执行的具体内容,并且抛出异常。同时在其函数的头部写出异常的信息。但是由调用函数的函数来编写处理异常的部分。

--------------------------------------------------------------------------------------------------------------------

3.2 继承和异常。

当一个子类继承一个父类时,子类重写了父类的某些方法。如果父类的这个方法有,异常说明的话,那么该子类也必须具有这些异常说明,必须与父类的该方法的异常类型相同,或者是该异常的 基类异常。

- ------------------------------------------------------------------------------------------------------------------

3.3 Checked and Unchecked Exceptions

首先在程序当中,我们可以检查一些错误,在这里我们称之为异常。但是异常分运行(run-time)异常和非运行时异常。(当然其中还有一些具体的分类。我在这里不做赘述。)首先我们的try-catch机制不处理运行异常。其次,我们也不处理 error。从下面的图中可以很清楚的观察到。

                

下面我们来谈一下Checked and Unchecked Exceptions

我们把使用 Catch or Declare Rule(使用异常接收和异常声明的方式统称)异常称之为Checked Exceptions,那不使用该规则的就被称之为Unchecked Exceptions。

--------------------------------------------------------------------------------------------------------------------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值