面向对象的编程-Application 23

Previously on OOP:

count() method and collectors can be employed as termination process for Stream. For collectors, developers are entitled to define their own collectors, which are composed of 4 parts: supplier, accumulator, combiner, and finisher.

在这篇文章中,我们将要开展Exception章节的学习。Exception仅在程序运行的时候出现,如果沿着hierarchy of invocation直到main函数都没有找到Exception handler,那么只能终止程序的运行,直接死机,并且在console中显示错误信息。

为了尽量避免程序的死机,开发者可以根据经验和代码的逻辑预测一下可能出现的run time errors,然后编写一些防御性的代码。比如,创建对象的时候可能会失败,后面再使用dotted notation调用的话,就会因为空指针而死机。如果每次在dotted notation调用之前都用if判定一下指针是否为空,那么死机的概率就会降低。

Exception handler和防御性代码有相似之处,都依赖于开发者的经验和代码的逻辑。但是,也有不(优)同(势):

(1)可读性比防御性代码的好。把可能会出现run time Exception的代码放在try block中,把Exception handler放在catch block中。

(2)能轻松做到Exception propagation, by throwing a new Exception.

本黄鸭来举一个NumberFormatException的例子。所有的Integer都能转化为字符串,但并不是所有的字符串都能转化为数字,比如今天的幸运数字就不能是“Duck”。如果把“Duck”这样的字符串转化为Integer会有什么效果呢?答案是NumberFormatException in run time。

本段代码中,我们的字符串是“x2”,不是一个数字。在try block中,我们试图把字符串用doubleIn()函数转化为数字。

如果出现Exception的话,就看catch block中有没有匹配的Exception。如果有,就执行那个匹配的catch block,之后就跳过其他所有的catch blocks,继续执行程序。如果没有,就顺着hierarchy of invocation向main函数传递,找Exception handler。如果一直找到main函数都没有找到,程序的运行只能被终止。

在本段代码中,catch block只有一个,是针对于DoubleItException的handler。里面会提示用户,刚才输入的字符串不是一个数字。当然,所谓的“输入”还要等到学完“I/O”章节才能实现。在执行完catch block之后,会提示“程序继续运行”。

下面,让我们看一看doubleIn()函数是怎样的。

函数声明中有关键字“throws”,说明应该会further propagate the Exception。“Character.isDigit()”函数很有可能是Character类中的一个static method,因为dotted notation前面不是object reference,而是class name。这个函数的功能是判定字符是不是数字。这个函数的参数就是要判定的字符,也就是字符串的第一个字符。

如果字符串的第一个字符是数字,会进入一个try block,把字符串直接cast到Integer类型,乘以2,最后返回。显然,一个字符串的第一个字符是数字不代表每一个字符都是数字,比如“233Duck”,还是没有办法转化为Integer类型。这是就会产生NumberFormatException,进入catch block,提示用户“Not a valid integer!”

如果字符串的第一个字符就不是数字,比如“Duck”,那么是必然不能转化为数字的。直接扔出一个新的Exception,类型是DoubleItException。这个Exception的类型是自定义的。

最后,看一下DoubleItException是怎样定义的。

DoubleItException的父类是Exception,而且所有run time Exception的父类都是Exception。在自定义的Exception类中,可以有Exception catching and propagation;也可以没有constructor之外的代码,把Exception handler编在其他类里面。在本课程中,后者比较常用,本黄鸭在这个类中也没有写Exception handler。

调用doubleIn()函数的人是main函数,所以Exception会马上propagate到main函数,也就是说,在main函数中必须要编写一个DoubleItException类的catch block,否则运行时可能会死机。

欢迎使用本黄鸭编写的小程序~

微信公众号二维码:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181025G1DXNM00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券