- 浏览: 298065 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
colin_i:
总结的很好,谢谢
Spring事务传播机制和数据库隔离级别 -
xiaoxi0324:
我想问,是否支持获取method内的逻辑分支,比如if分支,普 ...
javassist 学习笔记 -
z390174504:
不错,不错哦
web.xml 中的listener、 filter、servlet 加载顺序及其详解 -
chokee:
...
web.xml 中的listener、 filter、servlet 加载顺序及其详解 -
chenchangqun:
细致啊,楼主辛苦。
web.xml 中的listener、 filter、servlet 加载顺序及其详解
在看一些项目源码中,突然发现了异常的处理也是一门比较大的学问,其实处处都有学问,只是你是否留意而已。。好了,少点啰嗦,关于异常的处理,je上有个很精彩的讨论,我花了快一个钟时间才看完了,确实值得一看,帖子的网址:http://www.iteye.com/topic/2038
当然我这里写的,只是一个纯属的建议,大都是看了网上的帖子后,总结的。都是些前辈的经验。。下面开始吧。
——————————————————————————————————————————————
Java异常有三类:错误,运行时异常,检查型异常。
官方的观点是
第 39 条:最好为异常条件使用异常。也就是说,最好不为控制流使用异常。
第 40 条:为可恢复的条件使用检查型异常,为编程错误使用运行时异常。
第 41 条:避免不必要的使用检查型异常。
第 43 条:抛出与抽象相适应的异常。(使处理异常更直观)
在异常的使用上,专家的观点是很不一样的
C#作者Anders根本就忽略检查型异常。
Bruce Eckel,声称在使用 Java 语言多年后,他已经得出这样的结论,认为检查型异常是一个错误 —— 一个应该被声明为失败的试验。
——————————————————————————————————————————————
缺点:
缺点1,代码中包含了过多的catch,使得代码不清晰
缺点2,有时候捕捉的异常没有什么实际意义
缺点3,不够清晰的错误指示。
缺点4,过深的异常层次。
缺点4,性能。
——————————————————————————————————————————————
Eckel 提倡将所有的异常都作为非检查型的,并且提供将检查型异常转变为非检查型异常的一个方法,同时保留当异常从栈向上扩散时捕获特定类型的异常的能力
Rod Johnson ,他采取一个不太激进的方法。他列举了异常的多个类别,并且为每个类别确定一个策略。一些异常本质上是次要的返回代码(它通常指示违反业务规则),而一些异常则是“发生某种可怕错误”(例如数据库连接失败)的变种。Johnson 提倡对于第一种类别的异常(可选的返回代码)使用检查型异常,而对于后者使用运行时异常。在“发生某种可怕错误”的类别中,其动机是简单地认识到没有调用者能够有效地处理该异常,因此它也可能以各种方式沿着栈向上扩散而对于中间代码的影响保持最小(并且最小化异常淹没的可能性)。
——————————————————————————————————————————————
解决1:谨慎的抛出检查型异常。或者你认为,你可以处理它。否则,包装为运行时异常。
解决2:如果遵守1,2不是问题
解决3:异常不跨层,否则必须捕捉或者包装。
比如持久层丢出的SalException,你或者丢弃/处理/包装(为运行时异常),或者重新包装为业务层异常。保持JEE层的独立和异常的清晰性。
包装底层异常,保持异常链。
解决4:如果符合1,4也不是问题。再次强调,能捕捉就捕捉。
解决5:减少异常使用,减少层次。
——————————————————————————————————————————————
在je里面讨论,在上面的网址可找到:
robin认为异常是流程控制的一部分——当然,考虑到性能问题,这个流程不应该是大概率流程——也就是异常流程
例如用户登录
User login(String username, String password); throws UserNotFoundException, PasswordNotMatchException; try { UserManager.login(xx,xx); .... 用户登陆以后的主事件流代码 } catch (UserNotFoundException e){ ... 用户名称没有的事件处理,例如产生一个提示用户注册的页面 } catch (PasswordNotMatchException e){ .... 密码不对的事件处理,例如forward到重新登陆的页面 }
Potian则认为,没有用户是正常业务逻辑的一部分
If(!用户业务层.没有这个用户(用户名))错误提示界面;
If(用户业务层.检验密码(用户名,密码))登录成功;
else 登录失败;
Potian认为不应该在一个业务中包含了过多的责任。
muziq认为:
从做应用的角度看,我希望利用异常来管理显示在用户面前的错误提示,这样我就会将异常划分为两类,一类是可以显示给用户看的,或者说用户可以看的懂的,一类是给维护人员看的,就是通常说的系统错误,可以想象,让用户看到“空指针异常”是极不友好的行为。我们的项目中有一个专门显示错误的页面,它要么显示有具体业务含义的错误,要么就显示“系统错误”(然后维护人员可以从log中查找错误)。而前一类错误里面,每种错误总有一个不同的异常类和它对应,或者说,业务逻辑方法向表示逻辑抛出的异常,表示逻辑不需要分别处理(不要显示错误的除外),一律交给错误页面(其实是ErrorPageUIAction,我们用Struts),错误页面看是什么异常就显示什么错误提示,这里错误页面需要一个XML,XML里面定义了异常和错误提示的对应关系,当然XML里面只能有用户异常,不在XML里面的异常错误页面就会显示“系统错误”。业务逻辑事先将用户异常登记到XML中,这样错误信息还可以单独、统一的维护。
上面讲的是将异常展示到错误页面的方法,这其实只涉及到最后一层(Action)捕捉异常和业务逻辑层抛出异常的问题,而如何中间层内的异常如何抛、如何捕捉的问题考虑的思路一定是不一样的,不过,做应用系统的,业务逻辑层内部交叉引用的不多,所以这一块异常设计的矛盾并不突出。而如果你正在开发高度重用的组件甚至框架,异常就一定要好好设计一下了。
至于组件、框架的异常如何设计,我想只要去学JDK、Hibernate的那一套东西就没错了。能想到的就是,异常一定是调用者可以理解的,和方法的语义密切相关的。
——————————————————————————————————————————————
一些网上人的评论:
在servlet中,我喜欢仅仅简单的在action中调用最好一个业务层方法就可以完成此action的任务。这意味着我的servlet非常瘦,可以比较容易的被替换。如果采用了potian的办法,则意味着我要把业务层中的代码前移到servlet中来,这模糊了业务层的责任。解决的办法是回到老路子上来。
我还认为,没有异常的业务方法表达能力太弱,异常给了他们更丰富的表达能力。这使得业务层可以更丰富的表达业务意义。避免将业务责任分散掉。
———————————————————————————————————————————————
我的个人偏向:
我个人比较偏向je上muziq 的看法,项目的最终用户是网民,而大都不是计算机专业者,所以不管异常怎么处理,都要对用户有个友好的提示,尽力少,尽量简单。而对于程序设计者来讲又必须依据异常对程序进行修复处理。所以异常一般分为两类:一类是可以显示给用户看的,或者说用户可以看的懂的;一类是给维护人员看的。这是对于异常在程序表面上的处理。
而对于程序设计的底层(即代码的设计),异常尽量往高层抛出,让高层进行统一的处理,当然这是对于检查型异常而言。
如果一个异常是致命的,不可恢复的。或者调用者去捕获它没有任何益处,使用unChecked异常。
如果一个异常是可以恢复的,可以被调用者正确处理的,使用checked异常。
在使用unChecked异常时,必须在在方法声明中详细的说明该方法可能会抛出的unChekced异常。由调用者自己去决定是否捕获
相关的讨论比较好的帖子:http://www.iteye.com/topic/72170
文笔比较差,加上实际经验比较少,很难描述,还是看看代码比较容易懂,该实例是结合了ssh2:
Dao层:不抛出检查型异常,都由Hibernate包装成了运行期异常了
package dao; import dao.base.BaseDao; import model.User; public interface UserDao extends BaseDao<User,Integer>{ public void addUser(User user); public User getUser(String id); }
Dao 的实现层不写了,继承HibernateDaoSupport,由它实现,把异常都包装成运行期异常了。
service 层:抛出XXXService类对应的XXXException 异常
package service; import java.util.List; import exception.UserException; import bean.User; public interface UserManager { public void addUser(User user) throws UserException; public User getUser(String id) throws UserException; }
Service 实现层:抛出XXXService类对应的XXXException 异常
public class UserServiceImp implements UserService { static Logger log=Logger.getLogger( UserServiceImp.class.getName()); private UserDao userDao; @Override public User addUser(User user) throws UserException { try{ ........ }catch(Exception e){ //用日志记录错误信息 log.debug(e.getMessage()); //重新抛出新的异常,因为用户没必要知道详细的底层异常信息 throw new UserException("验证用户登陆出现错误,请重试"); } 。。。。setXXX()。。。。。 }
action 层:如果action 不处理UserException异常,则继续抛出,由拦截器拦截
public class AddUserAction extends BaseAction { private String name; private String password; public String execute() throws Exception{ //如果action 不处理UserException异常,则继续抛出,由拦截器拦截 } }
Struts2 配置文件:利用配置文件,把相应的异常转向相应的页面。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="GBK"></constant> <package name="struts" extends="struts-default"> <global-results> <result name="XXXException">/error.jsp</result> </global-results> <global-results> <result name="userException">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="exception.XXXException" result="XXXException" /> </global-exception-mappings> <global-exception-mappings> <exception-mapping exception="exception.UserException" result="userException" /> </global-exception-mappings> <action name="addUser" class="action.AddUserAction"> <result name="input">/WEB-INF/jsp/addUser.jsp</result> <result name="success">/WEB-INF/jsp/main.jsp</result> <result name="failure">/WEB-INF/jsp/addUser.jsp</result> </action> </package> </struts>
发表评论
-
根据PID获取本地的JMX地址
2013-10-02 10:42 0获取本地JMX地址的时候,应该使用/jre/lib/man ... -
开发问题总结(一)
2012-10-22 21:25 3179下面是在利用JDK的Instrument来编写调试工具的时候 ... -
java 启动命令解析
2012-10-16 22:17 2207前言 在看Btrace源码的时候,了解到 ... -
Jar文件及MANIFEST.MF 文件入门
2012-10-16 20:34 2989前言 在看Btrace相关源代码的时 ... -
mysql-Jdbc 驱动源码分析
2011-12-27 20:24 0这篇文章将对于mysql的jdbc驱动进行分析,结合平 ... -
Java并发编程笔记摘要
2011-08-19 14:16 1857多线程设计的目的是为了更多的榨取服务器硬件的性能, ... -
java.util.concurrent 之LinkedBlockingQueue源码分析
2011-03-30 16:08 3163LinkedBlockingQueue类 一个基于 ... -
java.util.concurrent 之ConcurrentHashMap 源码分析
2011-03-28 14:07 2743最近有点想研究下java.util.concurr ... -
log4j 配置
2010-10-11 10:49 12151. 配置文件 Log4J配置文件的基本格式如下: ... -
多线程时间记录logger类
2010-05-10 19:28 1865在近期工作中遇到个性能测试的打印的问题,由于log4j中如 ... -
enum 内部实现解析
2010-03-22 16:52 1954简单写个Enum 类型,然后反编译下 /** ... -
从JVM 内部看String 类型的问题
2010-03-22 16:40 1563关于String 类型,在面试题或者实际编程中都会经常 ... -
URLClassLoader 获取外部类(类加载器的用法)
2010-03-15 16:13 0package test; import java ... -
ThreadLocal 源码分析
2010-03-09 15:59 3578之前曾转载过相关 ... -
软引用、弱引用、虚引用 总结
2010-01-15 13:17 3589在看‘深入JAVA虚拟 ... -
Java 排序算法总结
2009-12-09 11:45 32131)分类: 1)插入排序(直接插入排序、希尔排序) 2)交 ... -
Java 输入输出流详解
2009-12-07 19:50 3549最近一段时间,处于失业状态,正好有机会对未理解的知识进行 ... -
深入java虚拟机-学习笔记
2009-10-10 16:37 01、Java 虚拟机 java 的面向网络的核心就是java ... -
java基础杂集(更新中···)
2009-03-01 10:46 12031、类的初始化顺序 ... -
ThreadLocal的原理和在框架中的应用
2008-12-28 23:04 2677概述 我们知道Spr ...
相关推荐
总结来说,LTE零流量小区的排除处理不仅是一门技术活,也是一门艺术。它要求相关工作人员具备专业的知识和丰富的经验,以及对网络状况的敏锐洞察力。随着技术的不断发展,我们有理由相信,通过不断优化处理思路和...
总结来说,JavaScript异常处理是一门艺术,需要开发者对异步编程和错误处理机制有深刻的理解。异常处理不仅能够提升程序的健壮性,减少用户的困扰,还能帮助开发者更好地定位和修复程序中的漏洞,从而提供更加流畅和...
3. **异常处理**:Java提供了一套强大的异常处理机制,通过try-catch-finally语句块来捕获和处理运行时错误。书中源代码可能会包含各种异常处理场景,有助于理解何时及如何使用异常处理。 4. **集合框架**:Java...
### 总结 《Android开发艺术探索》是一本旨在帮助开发者提升Android应用开发水平的书籍,内容涵盖了从基础知识点到高级技术应用的诸多方面,对Android系统的深入理解以及各种高级技术的详细讲解,对任何想成为高级...
理解如何通过异常处理来捕获和处理程序运行时的问题,以及如何使用调试工具来定位和修复错误,能显著提高开发效率。 最后,第二十五章至第二十七章可能涵盖了软件工程的相关话题,如版本控制、测试策略、项目管理和...
### 错误处理的基础指南 ...通过这些深入的讨论,我们可以看到错误处理不仅仅是一项技术活动,更是一种艺术形式,它要求开发者具备细致入微的观察力和创造力。希望本文档能为您的编程之旅提供有价值的指导和支持。
通过对面向对象编程、内存管理、异常处理、并发编程等方面的学习,开发者不仅可以掌握Java语言的核心技术,还能了解如何运用这些技术解决实际问题,提升软件工程能力。无论是初学者还是有一定经验的开发者,都能从中...
随着章节的深入,读者将接触到软件工程的原则,如模块化设计、面向对象编程、异常处理和调试技术。这些章节将帮助读者学会如何组织代码,使其更具可读性和可扩展性,这对于大型项目的开发至关重要。此外,作者可能会...
尽管文档链接并未提供具体章节或内容概述,但从标题“UNIX编程艺术(中文)”以及部分描述中提到的“原来linux里面命令的输出能够成为另一个命令的输入”,我们可以归纳总结出一些关键的UNIX编程概念和技巧。...
学习Java的基础语法、类库和异常处理是掌握大数据处理的前提。 2. **大数据**:大数据是指海量、高增长速率和多样化的信息资源。它涉及到数据的采集、存储、处理和分析。Java在大数据领域中的应用包括MapReduce编程...
连接管理包括打开连接、关闭连接以及异常处理等功能。在Pro*C/C++中,这些操作通常通过调用特定的API来实现。例如,`sqlcoci`函数用于打开连接,而`sqlcodci`则用于关闭连接。 #### 四、SQL语句的执行 **4.1 声明...
8. **错误处理与日志记录**:良好的框架应具备完善的异常处理机制,并提供日志记录接口,以便于调试和监控。 9. **性能优化**:C#的特性如Just-In-Time编译(JIT)、垃圾回收(GC)以及内存管理策略,有助于在框架...
- 注意代码的异常处理,避免程序崩溃。 - 对于更复杂的应用场景,可以考虑使用更高级的图形库或者第三方控件来增强艺术字的功能性和美观性。 通过本文的学习,读者不仅能够掌握如何在VB中使用WordArt,还能了解OLE...
4. 定期对艺术品进行检查,发现任何异常情况如锈蚀、裂痕等应及时处理,并记录在案。 5. 建立健全艺术品的保险制度,为高价值的艺术品购买保险,以减轻可能的经济损失。 6. 在拍卖前的展览阶段,需制定严格的参观...
- **错误处理机制**:建立完善的异常处理流程,提升系统鲁棒性。 #### 三、核心功能模块 1. **字体上传模块**: - 允许用户上传TTF或OTF等格式的字体文件。 - 对上传的字体文件进行有效性检测,确保格式正确且...
5. **异常处理**:C++的异常处理机制允许在程序运行时捕获和处理错误,提高程序的健壮性。书中会讲解何时、如何抛出和捕获异常,以及异常安全的编程原则。 6. **内存管理**:C++提供了对内存的直接控制,包括动态...
书中详细讲解了如何建立数据库连接、如何配置网络环境、如何管理用户会话以及如何处理异常和错误。 3. **数据处理**:数据是数据库应用的核心。本书在这一部分着重介绍了如何使用游标在Pro*C/C++中执行SQL查询和...
总结而言,微处理器技术的应用极大地提升了喷泉控制系统的智能化水平,不仅使得喷泉的表现形式更加多样化、艺术化,而且显著增强了系统的稳定性和可维护性。在环境美化方面,喷泉控制系统通过智能化改造,能够为人们...
4. 异常处理:设置全局异常处理器,保证系统在遇到错误时能给出友好的提示信息,而不是直接报错。 5. 测试:进行单元测试和集成测试,确保每个功能模块的正确运行。 在微信小程序方面,开发者需要熟悉微信小程序的...