前言
学java一段时间的时候,感觉exception这个概念看起来很简单,在实际中使用的时候却常不知道该如何取舍。尤其是关于exception的各种分类,以及checked exception, unchecked exception等,哪些是应该处理,该如何处理,哪些则不必要处理呢?各种exception,傻傻分不清。这里结合自己的一些理解,一并做一个讨论。
Exception的结构体系以及定义
我们在设计和执行程序的时候,往往会有太多其他的因素来影响到程序的正常的执行。比如说我们连接网络的程序出现网络连接断开,读取文件的时候发现文件不存在或者文件解析错误,访问某些资源的时候发现运行的程序没有足够的权限,等等。这些东西可能存在,在发生的时候像一个意外的发生,导致程序没法正常运行下去。在java里,这些都被定义为异常(exception)。
由于异常的导致原因、处理方式等在具体的情况下不同,所以它有一个整个体系化的定义。这里是一个关于exception系列相关类的结构图:
为了后面举例和讨论方便,在图中也列举了一些特定的exception。从图中我们可以看到,所有exception相关的类都继承自类Throwable,在它的下面又划分为两个部分,Exception和Error。在Error这一块,一些经常听到过的Error如OutOfMemoryError、StackOverflowError就来自VirtualMachineError。在Exception这一边,有IOException、SQLException等异常,另外一个比较典型的就是RuntimeException,我们见过的有的异常如NullPointerException和IllegalArgumentException就继承自它。
从结构图来看,这里的分类比较有意思。我们也可以笼统的看出点名堂来了。在Error和Exception这两个大类里,一些比较严重的问题,比如java虚拟机宕机了,内存被耗光了之类的问题,都定义在Error这个类下面。这些问题,我们可以看成是很严重的问题,一般是没法恢复的,在上面运行的程序也没法自己去处理。这就好比我们在一台机器上要运行一个程序,想通过这个程序来保证当机器宕机的时候来保存一些数据或者做一些恢复处理的工作,这几乎是不可能的。因为机器一宕机,里面的程序也就挂了,皮之不存,毛将焉附?
另外一类的Exception则不一样,这里发生的问题一般不是严重到了宕机之类使得程序都没法运行的程度。比如我们这里的IOException,可能是我在读取某个文件的时候出错了,但是整个运行程序的虚拟机还是好好的。而且我这个读取文件的程序也可以继续运行,取决于程序设计者的期望。实际上,我们大部分自定义的exception都是通过继承自类Exception。
关于Exception这个大类里的不同实际上他们的应用情景也有一定的差别。一个典型的就是RuntimeException,从字面上我们就可以看到,它主要是关于运行时的,在运行的时候出现的异常。对于这一类的异常,他们有的可以作为一种程序设计错误的提示。我们针对这种情况需要分析程序的设计及实现去修正这些错误。而有的是程序运行时碰到的问题,这种问题有的是运行的时候依赖于外部特定的环境或者设置,我们不能在程序里做其他有效的措施来恢复,就没必要去捕捉和处理它。
checked exception, unchecked exception
在很多场景下,常见的一个讨论就是checked exception和unchecked exception。对于checked exception来说,参照前面的类结构图,它官方的定义是继承自Exception这个类族里,除了RuntimeException的所有类。很多我们可以自定义的异常也归结到这一类里。常见的导致这种异常的原因有如下:非法的输入、网络连接或数据库连接错误等等。
对于unchecked exception来说,它主要指发生在运行时出现的错误,常见的一些原因比如有数组访问越界、传入null空指针错误等。
常见的一些处理手法
前面既然我们列举和讨论了这两类异常,那么当碰到这些异常的时候,我们该怎么去处理呢?从很多的书上我们看到的一个笼统的说法就是要保证一下几点:1. 提醒用户错误发生。 2. 保存所有必要的当前工作。 3. 允许用户优雅的退出程序。其实以上说的这几点都只是一个很含糊的描述,在具体问题的时候,我们到底该怎么办呢?这里,针对个人的一些体会,总结了这么几点。
总的来说,根据问题和具体应用场景的需要来做处理。对于checked exception来说,常见几种办法是:
1. 写log,用常用的log framework将错误信息记录下来。在记录了log信息之后再将异常信息向上传递。也有可能在这里直接退出。
2. 对于数据库之类的错误来说,可能需要关闭连接等信息。
3. 对于有的爬虫类应用来说,碰到这样的问题其实是很常见的,如果我们让它碰到异常就退出了并不是一个合理的选择,有时候可能是服务器繁忙,有的时候可能是那边网络暂时的阻塞。我们可能需要做一个重试的操作,比如说让当前的线程sleep多少秒,然后重试若干次,如果还是失败了再记录错误信息,退出。
4. 在一些用户交互的程序里,可能需要在界面做一些提示,比如显示某些特定的提示文字或者弹出提示错误信息的对话框,然后重置原来的进程让用户可以后面重试。
另外,对于一些unchecked exception来说,我们某些情况下也是可以捕捉和处理的。我以前曾经做过的某个项目有这么一个要求。在一些特定的配置文件项里设置了一些参数用来设定程序的属性。有的值表示合法的,可以enable它,有的则表示disable。但是如果用户在配置文件项里如果故意输入错误的信息该怎么办呢?这里为了项目的健壮性就统一将这些错误的配置信息解释成这些属性是disable的。当然,这里是需要结合具体应用的场景来看是否有意义。有的则确实是需要去作为一种unchecked exception让它出错或者终止,有的则可以继续运行。
总结
以前写程序的时候偶尔会想,要是写的程序都是在一个很理想的状态就好了。那个时候所有的输入和输出都是正确的,没有运行时候的各种意外发生。这样就不会有这么个讨厌的exception处理了。exception产生的很大一部分场景是在于我们自己设计的模块在和其他部分衔接的时候,我们不能保证其他部分传递进来的东西就是我们所希望的,所以为了保证程序的健壮性就需要考虑这么些场景。exception像一个声音提醒我们,人世间不如意,十有八九。关于checked exception和unchecked exception,笼统的来说是checked exception是有必要通过程序来处理的,在一些情况下可以在程序里重试或者恢复程序的执行。而对于unchecked exception,通常意味着他们要么是很严重的运行错误, 你没法恢复也没法处理,所以就让它这样吧,还有一些情况可能是本身程序的问题,需要设计者考虑程序设计和实现里的错误。在我个人看来,在某些场景下,捕捉unchecked exception并做一些处理也是有意义的。他们两者虽然有这么一个可以处理以及不可以处理的界限,但是不是绝对的,还是要具体问题具体分析。
参考材料
http://stackoverflow.com/questions/6115896/java-checked-vs-unchecked-exception-explanation
http://www.roseindia.net/java/java-exception/listofjavaexception.shtml
相关推荐
当我们使用Eclipse运行TOMCAT时,可能会出现"a java exception has occurred"的错误信息,本文将介绍解决该问题的办法。 一、双击TOMCAT SERVER出现"a java exception has occurred"的原因 当我们在Eclipse中双击...
`Throwable`类有两个主要的子类:`Error`和`Exception`。 - **Error**:通常用于指示系统级错误,这类错误往往是程序无法处理的(例如,虚拟机错误),因此不应该被程序捕获。 - **Exception**:代表可以被程序捕获...
Java的异常类都继承自`java.lang.Throwable`,主要分为两种类型:Error和Exception。Error是系统级的错误,如虚拟机错误、内存不足等,一般开发者无法处理,而Exception是应用程序可以预见并处理的异常。 声明异常...
Java异常处理是编程中至关重要的一个部分,它用于在程序运行时处理错误和不寻常的情况。在Java中,异常是一种事件,它中断了程序的正常流程。Java异常处理提供了五种关键字来帮助开发者有效地管理异常:`try`, `...
异常通常由异常类表示,这些类继承自Java的`java.lang.Throwable`类,最常见的是`Exception`类及其子类。 异常分为两种类型:检查性异常(Checked Exceptions)和运行时异常(Runtime Exceptions)。检查性异常是...
本项目中,"JAVA Exception Handling & UI Design" 涉及了如何在用户界面(UI)设计中结合异常处理,以及使用HashMap这一数据结构。 首先,我们来看看异常处理。Java中的异常分为两种类型:Checked异常和Unchecked...
Java程序在运行过程中可能会遇到各种异常,其中"nested exception is java.lang.OutOfMemoryError: Java heap space"是一个常见的问题,通常发生在程序试图分配超过堆内存限制的空间时。这个错误表明Java虚拟机(JVM...
java development part of exception
JD-GUI是使用C++开发的一款Java反编译工具,它是一个独立图形界面的Java源代码“.class”文件反编译工具。 JD-GUI是使用C++开发的一款Java反编译工具,它是一个独立图形界面的Java源代码“.class”文件反编译工具。
自定义异常是在Java中通过继承`java.lang.Throwable`或其子类(如`Exception`或`Error`)来实现的。通常,我们选择继承`Exception`类,因为它用于表示程序可以恢复的错误,而`Error`则用于表示系统级的严重问题,...
Java是一种广泛使用的高级编程语言,由Sun Microsystems公司(现在是Oracle公司的一部分)的James Gosling和他的团队在1995年发布。Java是一种面向对象的语言,以其可移植性、健壮性和多线程能力而闻名。 ### Java...
Java异常类继承自`java.lang.Throwable`类,它有两个主要子类:`Error`和`Exception`。`Error`通常用于表示系统级或不可恢复的错误,而`Exception`用于应用程序可以捕获和处理的异常情况。 15.5 重新抛出异常 有时...
Java异常 Exception类及其子类详解 Java异常Exception类及其子类是Java语言中异常处理的核心部分。异常是指程序在执行过程中出现的非正常情况,例如除数为零、数组索引越界、类型转换错误等。Java语言所有的异常都...
在给定的标题 "java.text.ParseException: Unparseable date: 2/10/2010 15:20:05" 中,问题的核心在于日期格式“2/10/2010 15:20:05”没有被正确地识别和解析。 这个异常表明,程序正在尝试将这个日期字符串转换成...
### Java Exception 几种不适当的处理 ...在实际项目中,应该遵循最佳实践,如合理使用try-catch-finally结构,明确区分和处理不同类型的异常,以及充分利用Java的异常机制,以构建更加可靠和高效的软件系统。
例如,可以创建一个匹配"Caused by:"模式的正则表达式,如`"Caused by:(.*)"`,然后使用`Pattern`和`Matcher`类来搜索堆栈跟踪字符串,找到并提取相关信息。一旦匹配成功,就可以通过`Matcher.group()`方法获取捕获...
在使用Oracle 10g的过程中,部分用户可能会遇到一个特定的问题:在登录企业管理器(Enterprise Manager, EM)时,系统会报错“java.lang.Exception: Exception in sending Request :: null”。这个问题虽然不常见,...
总的来说,`ArithmeticException`是Java中常见的运行时异常之一,通过合理的异常处理和输入验证,我们可以避免这类异常的发生,提高程序的健壮性。理解并妥善处理这种异常对于编写稳定且可靠的Java程序至关重要。
java Exception中Throwable和Exception之间的区别