`

java中异常应该如何处理(续 + 转)

    博客分类:
  • java
阅读更多

我们知道java的异常有两个大类,一种是check Exception,一种是runtime Exception。
1.check exception:如果一个方法抛出check exception,调用代码要么catch要么在方法声明中重抛该异常。
2. runtime Exception:如果一个方法抛出RuntimeException,则调用代码可以catch,也可以忽略。由于可以忽略,初学者可能非常喜欢。

为了探究Exception的本质,让我们回到exception的历史上。exception的目的是方便我们查找问题以及简化我们的业务逻 辑。在c语言中没有exception一说,所有程序的状态都是需要代码控制,往往通过函数的返回值来得到函数执行的状态。让我们看一个简单例子,假如一 个函数需要传递一个参数id,从DB中获取对应id的值,而id的值的范围是所有int,调用DB过程中可能发生一些错误,调用者如何知道返回的值是id 真实的值还是异常状态呢?我们只能通过指针回传值,而返回值作为执行的状态。这样的函数看起来就别扭。当我们增加exception功能后,这样的问题处 理起来就简单多了,只需要函数的声明中增加expeition就可以了。显然这种方式更加符合人的思维,也直观明了。因此在现代程序开发语言中,异常处理 成了必不可少的语言特性。

程序员写代码容易,但真正要把异常处理好可真不是那么容易的。我们知道异常的真正目的是为了方便知道究竟是什么原因出错了。一种是业务逻辑的错 误,一种是系统错误。比如一个函数通过传递一个userId去获取用户信息,有几种情况:正常获取到用户信息,DB未启动,连接不上,网络断掉,连接不 上,connection申请不到,已经达到上限。或者是用户不存在。显然我们可能需要针对不同的情况代码逻辑做相应的处理。比如如果是连接不上,可能需 要我们重试几次,如果是用户不存在我们需要友好提示你查找的用户不存在,如果是DB没有启来,则需要提示系统错误,有可能需要通知相关的DB人员。因此好 的程序员一定要仔细对待每一个异常的处理。正确的异常处理是保证程序健壮性的关键之一。

那么我们什么时候该抛出check exception,什么时候该抛出runtime exception。前面已经解释了两者的差异。check exception需要强迫调用者必须处理它,而runtime exception不必。既然强迫别人做事总是会让人不爽,runtime exception是不是最佳选择呢。当然不是,否则sun就不会搞出这两类异常。一个相对比较有效的建议是如果抛出的异常需要调用者关注并可以采取措施 进行不同的代码流程控制的,check exception无疑是唯一的选择。而runtime exceptin是针对那些“我这里有问题发生,但是告诉你你也不能解决”的问题。当然有些时候由于接口声明异常的限制,最初的接口没有声明异常,导致实 现该接口时即使有异常抛出也只能乖乖地抛出runtime exception,因为别无选择。这也给我敲了警钟,如果你声明接口,除非你有十足把握没有错误出现,建议你声明一下异常吧。

但是check exception带给我们最大的麻烦是,代码遍地是try catch块,主要的业务流程被这些try catch块分割得支离破碎,看到这也的代码确实心烦。有什么好办法吗?答案是肯定的。我们的程序总是由多层代码构成,以及同一层的不同业务包构成。我们 需要切分不同层以及不同业务包,比如DB层,统一抛出SqlException,文件相关的接口统一抛出IOException,如果是business 层,与用户管理相关的模块,统一抛出UserException,在不同业务层及模块间调用时,wrap一下exception,统一由抛出该层相关的 check exception,这样,内部的业务逻辑处理就非常简单,可以尽量少的看到try catch块,而且又能合理利用exception的好处。
对于什么时候该使用Runtime Exception,什么时候该使用Check Exception已经有一定认识了,让我们再次回归到Exception的本质,Exception一个非常重要的作用是需要告诉调用者发生了何种错 误,错误发生的地方在哪里。Java中的Exception的callstack显然非常有用。可以知道何处发生了何种错误。因此我们通常会将异常通过日 志工具记录到日志里,以方便查找问题。这个话题似乎不值得一提,发生错误的地方记录log日志是显然的答案。其实未必,很多看起来显而易见的问题仔细深究 问题就不那么显然了。如何打印Exception到日志中,需要回答几个问题。哪里记,记什么,日志级别怎么定?并不是任何发生异常的地方都该记,并不是 发生了exception都该记为error级别,不是所有发生问题的地方都需要把Exception的调用栈打出来。另外一个问题是并不是所有的地方都 可以把一个异常包装为一个新定义的异常抛出。以下是我在代码编写过程中总结的一些经验,可能有些地方也不仅其然。

哪里记?应该在exception的末端记录发生的异常。何为exception末端?如果程序代码需要处理Exception,并且不再将 Exception外抛,或者在RPC应用中,任何对外提供的调用的方法实现都应该称为Exception末端,都需要对Exception进行处理。这 样的好处是,在日志文件中不会看到一个Exception有很多处重复出现,同时又保证对异常的跟踪有效。必须要说明一点的是,如果是RMI接口,如果接 口声明有异常,难到还需要记录日志并重新处理吗?这是跟RMI的机制有关,由于我们的Exception可以被嵌套,比如在抛出ExceptionA时丢 进去一个ExceptionB,这在Exception包装过程中是常用的伎俩,而且我们非常鼓励这样做,以便我们能发现问题的root cause。当客户端收到异常的时候,如果要打印这些异常信息,需要反序列化对于的异常,由于客户端只有ExceptionA类,无法找到 ExceptionB类,这打印这样的异常将会导致NotFoundClassException。在我们DMS中RMI调用就遇到过类似情况。像web 应用的mvc层,对外就不能再抛异常了,因为再往外抛就到用户那里了。而任何系统都不希望用户看到exception,都应该转换为用户友好的信息。

记什么?从我个人观点来看,如果遵循我上面的规则(如果catch了一个Exception,要么业务上能处理,并记日志,要么包装为其他异常, 如果包装为其他异常,应该将异常嵌套进去),应该把Exception的调用栈打印处理。调用栈是我们分析问题最有效的信息。之所以说是按个人观点,我觉 得这里应该有不同意见。而且我看到很多代码中没有完全遵循这种规则。
日志级别。如何记日志级别相对比较简单,能够在业务逻辑上处理掉的,显然不应该抛错,当然也就不用记,有些Exception是为了保护用,一旦 catch这样异常,可能需要提醒系统人员可能有不应该出现的异常状态,但不影响业务逻辑,这样的异常打个warning级别就好了,其他情况都该打成 Error级别。

 

文章来源:http://zoutm.iteye.com/blog/707393

分享到:
评论

相关推荐

    Java实现断点续传程序

    4. **异常处理**:包含网络中断、文件系统错误等异常的捕获和处理逻辑。 5. **进度调度器**:负责定时更新和通知传输进度,可能与UI线程进行交互。 综上所述,Java实现断点续传涉及了网络通信、文件操作、错误处理...

    java断点续传,刚刚整理出来多线程处理

    3. **异常处理**:网络中断或文件错误可能导致线程异常,必须有适当的异常处理机制,确保程序能优雅地处理错误并尝试恢复。 4. **线程协调**:所有线程完成后,需要合并文件和更新文件元数据(如修改时间),这通常...

    java ftp 多线程 断点续传等知识

    为了实现以上功能,你需要对Java并发编程有深入理解,包括线程同步、共享资源管理以及异常处理。同时,熟悉Apache Commons Net库的API使用也至关重要。`CuteFTP80.rar`可能是包含一个FTP客户端软件的示例,你可以...

    xuchuanftp_java_FTP断点续传_

    描述"Java上传文件到FTP服务器,支持断点续传"明确了Java代码的目标:通过FTP协议将本地文件上传到远程FTP服务器,并且在上传过程中能够处理因各种原因中断的情况,继续从上次停止的地方开始,而不是重新开始整个...

    java大文件分块上传断点续传demo

    4. 服务器端处理:服务器端需要能够接收和合并这些分块,确保按照正确的顺序组合成原始文件,并能识别并处理续传请求。 5. 错误处理与重试机制:当上传失败时,能识别错误并决定是否重试,以及重试的策略。 6. ...

    java FTP多线程 批量 断点续传

    Java FTP多线程批量断点续传是一种在Java编程中实现高效、稳定文件传输的方法,尤其适用于大文件的上传和下载。在这个过程中,我们利用FTP(File Transfer Protocol)协议,结合多线程技术和断点续传功能,可以显著...

    java断点续传上传

    5. 异常处理:客户端需要处理各种网络异常,如超时、连接断开等,并决定如何重试或终止上传。 6. 安全性:在传输过程中,可考虑使用HTTPS确保数据安全,防止数据被窃取或篡改。 总结,Java实现断点续传上传涉及到...

    java实现断点续传

    Java 实现断点续传是一项在文件下载或上传过程中经常用到的技术,它允许用户在中断网络连接后从上次停止的地方继续,而无需重新开始整个过程。这项技术尤其适用于大文件传输,可以大大提高效率和用户体验。以下是...

    java断点续传Demo

    Java 断点续传技术是网络传输中一种高效的数据下载策略,它允许用户在中断下载后从上次停止的位置继续下载,极大地提高了大文件传输的...在实际开发中,我们需要注意处理各种异常情况,以提供稳定可靠的断点续传服务。

    java实现多线程断点续传下载

    在Java编程中,多线程和断点续传下载是两个关键的概念,它们在实际的网络应用开发中具有广泛的应用。本文将详细讲解这两个技术及其在Java中的实现。 首先,让我们了解一下多线程。在计算机科学中,多线程是指在一个...

    java实现ftp断点续传

    7. 在异常处理中,捕获中断异常并记住中断位置,以便下次重试时使用。 8. 在传输完成后,关闭数据连接和控制连接,`FTPClient.logout()`和`FTPClient.disconnect()`。 在实际应用中,我们还需要处理各种异常情况,...

    java 段点续传 例子

    7. **异常处理**:网络中断、服务器错误等情况可能导致下载失败,因此需要有良好的异常处理机制,以便在出现问题时能恢复到上一次的下载状态。 在提供的压缩包中,`[网络] 用Java实现断点续传(HTTP) (zz)--青苹果....

    java断点续传

    7. **错误处理**:网络中断或服务器错误是常见的问题,因此需要有重试机制和异常处理代码。如果下载失败,程序应能够恢复到之前的状态,从上次断点继续。 8. **文件合并**:所有下载完的块最终需要合并成完整的文件...

    用Java 实现HTTP断点续传技术文档【附实例代码】

    6. **异常处理**:处理可能出现的各种异常情况,如网络中断、服务器错误等。 7. **循环直至完成**:重复上述步骤直到文件完全下载完毕。 #### 示例代码 以下是一个简单的示例代码框架,用于演示如何使用Java实现...

    java断点续传源代码

    综上所述,Java断点续传技术涉及网络编程、文件操作和异常处理等多个方面,通过合理的实现可以显著提高大文件下载的效率和用户体验。理解并掌握这些知识点对于开发高效的文件下载应用至关重要。

    java+webuploader+Demo

    在这个过程中,我们需要处理文件的合法性检查(如大小、类型限制)、异常处理以及文件命名策略等。 3. 文件上传流程: - 前端选择文件:用户在Web页面上选择要上传的文件,WebUploader组件会监听这些事件。 - ...

    java下载软件断点续传

    此外,考虑到网络状况可能不稳定,我们还需要实现异常处理和重试机制。当下载过程中出现网络错误或服务器返回非206(表示部分内容)状态码时,我们可以暂停下载,记录当前状态,并在条件允许时自动或手动尝试重新...

    java edftp 断点续传

    Java EDFTP 断点续传技术是Java编程中用于FTP(File Transfer Protocol)文件传输的一种高级功能,它允许用户在上传或下载大文件时中断进程,然后在稍后的时间点继续从上次中断的地方开始,而不需要重新传输已传输的...

    基于java的多线程断点续传程序源代码

    5. **错误处理与恢复**:如果某个线程在下载过程中出错,程序应该能够捕获异常,记录错误信息,并尝试重新启动该线程或整个下载任务。 6. **进度反馈**:提供用户界面更新下载进度,让使用者了解当前下载状态。 这...

Global site tag (gtag.js) - Google Analytics