Java的Error和Exception
程序在运行时难免会存在少量意外的情况的发生,只有正确的解决好心外情况,才可以保证程序的可靠。Java提供了一套相对完善的异常解决机制,能通过用一些的代码达到可靠的效果。Java语言的设计者根据不同的异常情况分成了Error和Exception两类,该两类都继承了Throwable类,在Java中只有Throwable类可以够抛出和捕获,因而它为Java异常解决机制的基础。
Error
Errror类形容了Java运行时系统的内部错误和资源耗尽错误,绝大部分的Error都会导致程序处于非正常的、不可恢复的状态,由于是非正常且不可恢复的,因而程序不应该抛出这种类型的错误。假如出现了这样的错误,除了通告给使用户,并尽力使程序安全地终止外,再也无可以为力了。但这种情况很少出现,常见的Error如:OutOfMemoryError, StackOverFlowError等。
Exception
Java语言规范将派生于Error类或者RuntimeException类的所有异常称为unchecked异常,所有其余的异常称为checked异常。
unchecked异常
在Exception结构下,uncheckn异常继承于RuntimeException,也就是常说的运行时异常,如NullPointException,ArrayIndexOutOfBoundsException和illegalArgumentException等异常,该类异常在编译期不强制要求捕捉,通常是由于程序逻辑错误造成的,因而假如出现了该类异常,多半是你自己的问题,需要修改程序避免这类异常。
PS:RuntimeException容易让人误会,事实上所有的异常都是发生在运行期。
checked异常
与unchecked异常的差别在于,该类异常在编译期就强制要求抛出或者捕获,如IOException、InterruptedException等,需要用try…catch…finally块或者者try-with-resources等进行解决,或者者通过throw直接向上层抛出异常。
Exception实践
仅捕获有必要的代码
因为try-catch块会产生额外的性可以开销,会影响JVM对代码进行优化,因而建议仅捕获有必要的代码段,尽量不要一个大的try包住整段的代码。同时,也意味着不要用异常来控制代码的流程,远比用if/else等控制语句要低效。
捕获特定异常
尽量不要捕获Exception这样的通使用异常,而是应该捕获特地的异常,如在上述中用IOException。直接捕获Exception会降低程序的可读性,并且我们需要保证程序不会捕获到我们不希望捕获的异常,比方,我们更希望RuntimeException被扩散出来,而不是被捕获。
不要忽略异常
;有时候我们会认为某段代码根本不会发生异常,而对异常进行忽略(在catch块中不做任何操作)。假如我们不把异常抛出来或者者输出到日志之类,那么一旦异常发生,程序可可以在后续代码以不可控的方式结束,没人可以够轻易判断是哪里以及什么起因产生了异常。
输出异常信息到日志中
try { ... OutputStream os= new FileOutputStream(file); os.write(byteArray);} catch (IOException e) { e.printStackTrace();}
在试验代码中,我们经常直接输出异常信息到标准错误(STERR)中,但是在略微复杂的环境中,这不是一个合适的选择,尤其是在分布式的系统中,你根本无法判断信息输出到了哪里。所以最好用日志产品记录错误信息。
考虑将异常上抛
我们有时候会遇到捕获异常后不知道如何解决的情况,那么与其捕获异常,不如将异常直接抛出或者者捕获后经过肯定解决,构建一个新的异常抛出。往往在更高层面,由于有了清晰的业务逻辑,会更清楚合适的解决方式。
注意try…finally块中的return
public static void main(String[] args) { System.out.println(getValue()); } public static int getValue() { int i = 1; try { return i; } finally { i ++; retutn i; } }
在Java中,在try块中执行return语句前会执行finally块,假如在finally中也有一个return语句,那么try语句块中的return将不会被执行。如上述中结果将返回2。
public static void main(String[] args) { System.out.println(getValue()); } public static int getValue() { int i = 1; try { return i; } finally { i ++; } }
再看这段代码,按照之前的逻辑,变量i在返回前先调使用了finally块,i会变为2,但实际上结果任然为1.实际上,Java 虚拟机会把 finally 语句块作为 subroutine(子程序)直接插入到 try 语句块或者者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,而后通过 return 或者者 throw 语句将其返回给该方法的调使用者。更加的详细内容请查看 Java关键字 Finally执行与break, continue, return等关键字的关系
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java的Error和Exception