这是我在一家外企的时候,一个面试官对我提出的问题.当时我回答的是为了帮助开发者定位错误吧!面试官对我的回答并不满意,事实上我对自己的回答也并不满意,今天我终于给出一个能让我自己满意的答案。
什么是异常(Exception)?
java的基本原理就是"形式错误的代码不会运行"《java编程思想》第四版
个人觉得上面的那句话翻译的还是有一点问题的,感觉原文应该是java的基本思想就是"形式错误的代码不会执行",但是又没找到英文原版,没法贴原文。后面有时间的话,会找一下原版,这本书还是很经典的。
在回答这个问题之前,我问我自己异常是什么,我的回答是异常是程序在运行期所犯下的错误.不得不说,这个回答相当的不那么令人满意。
于是,我去官方写到的指导书中去寻找这个问题的答案(官方有写教程叫The Java™ Tutorial,上百度直接搜java Tutorial就可以直接搜到)
The Java programming language uses exceptions to handle errors and other exceptional events.
java 采用异常去处理错误和意外的事件
对于什么是异常? 官方给出的回答是:
An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions.
异常是在程序执行过程中发生的扰乱正常指令流的事件
disrupt也有中断的意思。
也就是说异常是程序在执行过程中一些使得程序发生错乱,中断的事件。原因可能是多种多样的,程序员的错,或者环境的错等等。
为什么要引入异常机制呢?
站在语言设计者的角度上,如何处理这种错误呢? java给出的答案是抛出或者捕获,抛出就是不处理,捕获就是有选择的处理。
这让我想到了C语言,C语言没有异常机制,它是怎样处理错误和意外的事件呢? 似乎上开发者自己处理,
如下图:
输出结果为:
在java中这段程序执行不了的,a[5]是打印不出来的,会报Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
再比如: 除0操作.在C语言中,你照样也是可以跑的通的,虽然你的程序可能会崩掉。
为了测试这是IDE给出的提示还是C给出的提示,我决定在Linux下执行一下:
这点抛的异常还是很让我疑惑的,浮点数异常,我没有踩任何一种编程语言的意思,java在运行期间出现了错误是比较直观的。
在C语言中似乎并不数组越界看做是一种运行时的错误。
在程序很短的时候,你可能很容易一眼就可以看出你错在哪里,但是程序达到了上百行之后呢,你的程序崩掉了,然后你并不知道发生了什么?反正它崩了。但是在java中它会给你一个简介而明了的提示,
,甚至还告诉你错在哪里。
我已经好久不碰C++了,只写了一个非常简单的C++程序来测试C++是如何处理程序在运行过程遇到的错误,
似乎跟C语言的反应是一致的,不过我在IDE中发现了这个:
为了测试这是IDE给出的提示还是C++给出的提示,我决定用命令行执行一下:
看来C++是有的。
与C++类似,捕获错误最理想的是在编译期间,最好试图在运行程序以前。然而,并非所有错误都能在编译期间侦测到。有些问题必须在运行期间解决,让错误的缔结者向接收者通过一些手续向接收者传递一些适当的信息,并使其知道该如何正确的处理遇到的问题。----《java编程思想》
结合java编程思想,我们可以给出答案的第一点: 异常机制可以帮助我们定位错误,给出错误出现的原因,帮助我们解决问题。
为什么写到这里的时候,脑中突然浮现这么一句话: 异常机制也提高了java程序员的下限.为了避免一些开发者用不好数组越界带来的好处,java的设计者直接就屏蔽了数组越界操作,即裁定数组越界是违法操作。
在C++和其他早期语言中,可通过几种手续来达到这个目的。而且它们通常是作为一种规定建立起来的,而非作为程序设计语言的一部分。典型地,我们需要返回一个值或设置一个标志(位),接收者会检查这些值或标志,判断具体发生了什么事情。然而,随着时间的流逝,终于发现这种做法会助长那些使用一个库的程序员的麻痹程序。他们往往会这么想:"是的,错误可能会在其他人的代码中出现,但不会在我的代码中"。这样的后果是他们一般不会检查是否出现了错误(有时出错条件确实显得太愚蠢,不值得检验;)
另一方面,若每次调用一个方法时都进行全面、细致的错误检查,那么代码的可读性也可能大幅度的降低。由于程序员可能仍然在用这些语言维护自己的系统,所以他们应该对此有着深刻的体会: 若按这种方式控制,那么在创建大型、健壮、易于维护的程序时,肯定会遇到不小的阻挠。引自《java编程思想》第四版
java的异常机制增强了程序的健壮性、可维护性。java在设计之初就着眼于程序的可维护性与健壮性。
这句话怎么理解呢? 就是我们在写程序的时候为了检测或处理程序在运行中可能出错的情形,就可以从异常机制中获益
你可以选择抛出或者是捕获。
"异常"(Exception)这个词表达的是一种“例外”情况,亦即正常情况之外的一种“异常”。在问题发生的时候,我们可能不知具体该如何解决,但肯定知道已不能不顾一切地继续下去。此时,必须坚决地停下来,并由某人、某地指出发生了什么事情,以及该采取何种对策。但为了真正解决问题,当地(问题的发生地)可能并没有足够多的信息。因此,我们需要将其移交给更级的负责人,令其作出正确的决定(类似一个命令链。 异常机制的另一项好处就是能够简化错误控制代码。我们再也不用检查一个特定的错误,然后在程序的多处地方对其进行控制。此外,也不需要在方法调用的时候检查错误(因为保证有人能捕获这里的错误)。我们只需要在一个地方处理问题:“异常控制模块”或者“异常控制器”。这样可有效减少代码量,并将那些用于描述具体操作的代码与专门纠正错误的代码分隔开。一般情况下,用于读取、写入以及调试的代码会变得更富有条理。引自《java编程思想》第四版