论坛首页 Java企业应用论坛

为什么 Java 中要使用 Checked Exceptions

浏览 193217 次
该帖已经被评为精华帖
作者 正文
   发表时间:2003-12-18  
我们不是为了OO而OO,OO不是拿给别人炫的,OO使代码更接近用例的自然语言,OO使代码更容易维护、修改,设计、实现过程中应首先考虑良好的体系结构、易读的代码,其次才是性能的问题。
我对Exception的理解和Robbin不谋而合,但我想这是因为对OO具有比较一致的理解。不过,“Exception<>异常”说成“Exception<>错误”可能更贴切一些。
0 请登录后投票
   发表时间:2003-12-18  
robbin 写道
我没有资格评论大师们的观点,但是我知道绝大多数的Java程序员根本就没有领悟“Exception”的真正用处。他们就是把Exception当做异常来理解,没有明白Exception实际上代表了一个UseCase中的异常流的处理。

在使用UseCase来描述一个场景的时候,有一个主事件流和n个异常流。异常流可能发生在主事件流的过程,而try语句里面实现的是主事件流,而catch里面实现的是异常流,在这里Exception不代表程序出现了异常或者错误,Exception只是面向对象化的业务逻辑控制方法。如果没有明白这一点,那么我认为并没有真正明白应该怎么使用Java来正确的编程。



我不是很同意robbin的观点,Exception 是为了处理异常流程或者说是意料不到的情况,在提到的登陆的例子里面,密码错误是正常的流程,为什么要抛一个异常出去?即使象上面提到的返回int ,我个人也觉得没有什么不对(虽然我不会这样写),因为登陆你可以估计会有几种情况发生:1:登陆成功,2:用户不存在3:密码错误 4:用户过期 。。。这属于正常流程。
但有些情况下是存在使用Exception 来作为处理不同流程的条件。
BTW:在OO 里面出现一些面向过程的编程手法也没有什么不可,只要程序稳定符合流程和符合实际需要。
0 请登录后投票
   发表时间:2003-12-18  
孤魂一笑 写道

我不是很同意robbin的观点,Exception 是为了处理异常流程或者说是意料不到的情况,在提到的登陆的例子里面,密码错误是正常的流程,为什么要抛一个异常出去?即使象上面提到的返回int ,我个人也觉得没有什么不对(虽然我不会这样写),因为登陆你可以估计会有几种情况发生:1:登陆成功,2:用户不存在3:密码错误 4:用户过期 。。。这属于正常流程。
但有些情况下是存在使用Exception 来作为处理不同流程的条件。
BTW:在OO 里面出现一些面向过程的编程手法也没有什么不可,只要程序稳定符合流程和符合实际需要。


那么UseCase里一些Alternative和Exception Flow怎么方便地用Java来实现?
0 请登录后投票
   发表时间:2003-12-18  
没有谁对谁错,不过我目前还是比较接受potian的说法。
也很符合我对异常的理解。
0 请登录后投票
   发表时间:2003-12-18  
在用例里面,主事件流也被称为愉快的(Happy)流程,就是说这个过程使使用者和系统都感到愉快,皆大欢喜,它是需求分析时首先考虑的内容,UML鼓励我们先集中精力解决主要问题,对不同的问题(主事件流、异常事件流)分别进行分析,各个击破。Java的Exception机制与UML的思想是一致的。我说Exception不等于错误也是这个意思。在我们的系统中登录的接口就是会分别抛出用户不存在和密码无效的异常,这时业务逻辑层需要考虑的事情,表示逻辑不需要分别捕捉、分别处理,有专门的错误页面去根据异常类显示不同的提示信息。
0 请登录后投票
   发表时间:2003-12-18  
dlee 写道
关于 Java 中引入的 Checked Exceptions,目前存在着很多反对意见。正方的观点是引入 Checked Exceptions,可以增加程度的鲁棒性。反方的观点是 Checked Exceptions 很少被开发人员正确使用过,并且降低了程序开发的生产率和代码的执行效率。
正方代表 James Gosling
http://www.artima.com/intv/solid.html
反方代表 Anders Hejlsberg
http://www.artima.com/intv/csdes.html
中文版:http://www.csdn.net/develop/article/22/22612.shtm
两位都是大师级的人物,观点的碰撞非常精彩。

我个人更倾向于 James Gosling 的观点,即稳定性更加重要。C++ 程序的后期维护成本远远高于 Java 程序,更不要说前期的开发成本了。Java 要担负企业级的核心应用(HA 24X7),没有这些系统级的保证是不可能的。C++、Delphi 都中没有 Checked Exceptions,所以 Anders 设计 C# 时也没有加 Checked Exceptions。当然我并不是说没有 Checked Exceptions 就一定不能写出稳定的程序(你说,我就是比你牛,我用汇编语言都能写出稳定的程序!),但是显然使用 Java 语言写出稳定的程序比用 C++ 更容易。Checked Exceptions 就是编程语言所提供的系统级保证,能否用好是你自己的问题了,并不象 Anders 说的那样严重。我觉得 Anders 大师对于企业级应用并没有太多的概念。James Gosling 看了 C# 的设计后觉得不过如此。当然这只是大师本人的观点,我们未必一定要接受了。



这是个很好的话题,我是开发应用系统的,更喜欢Unchecked Exception,但我知道对于JDBC/Hibernate这些底层类库来说,Checked Exception也是必不可少的。

抽象一点说,Checked Exception是一种好的设计,可以让代码更加健壮。但XP里也有一条,不要设计过度。

对于应用系统来说,大多数Exception情况下,只需要中断操作,提示用户错误信息,很少有需要外部代码捕捉甚至进行处理的,所以绝大多数Exception应该是UnChecked Exception (RuntimeException),捕捉到的底层系统错误也应该封装成Unchecked Exception抛出。

UncheckedException带来的不仅是代码简洁,而且给代码更大的复用性。
0 请登录后投票
   发表时间:2003-12-19  
是的,更明显的表达语义是OOP的特点,过程化的编程不是完全做不到,是很难像OOP一样表达的这么好。我认为强调语义对于对象编程很重要。
0 请登录后投票
   发表时间:2003-12-19  
无道 写道
我认为函数抛不抛异常与函数本身的语义密切相关,在函数正常返回的情况下,函数完成了其即定的语义,在返回异常时,说明函数不能顺利地完成语义。因此login函数当然应该有UserNotFoundException异常,因为login函数的语义就是用户登录,而不是看用户是否存在;isUserExist当然就应当返回boolean,因为它就是用来检查用户是否存在的,而不需要抛出异常来表明。

这是对的,如果你写的login(user,password)返回一个UserDTO,那么就应该抛出例外,因为你这个方法预期将返回一个正常的User。(这适合于普通的登陆界面,直接把这个UserDTO放到Session里面去)
如果你的login是为了判断能不能成功,那就不是例外。这种情况也很多,譬如登陆以后需要根据目前的用户状态判断是否要改用户补充信息、确认等等。这时候往往第一步判断是否成功,后面根据不同的状态取得不同的用户信息

例外是处理异常的情况,和你类(服务类)的意图密切相关,同一种情况,在某些方法里面是例外,而在另外方法里面就不是例外了。
0 请登录后投票
   发表时间:2003-12-19  
所以我不太喜欢第一种方式,因为第一种方式实际上在同一个方法中包含了两个责任,验证是否合法以及验证合法以后返回用户信息。这造成了验证合法不能被细粒度重用(如我第二种情况,当我需要不同的用户信息时)。当然,在一个不需要进行多步认证的应用程序里面,这已经足够了,可以等到第二种情况出现的时候才去重构。
0 请登录后投票
   发表时间:2003-12-22  
就我个人的理解,Exception主要的应用地方应该是,业务逻辑处理能力之外(人力不可预计)的地方.就想前面举的用户登陆的例子.除正常登陆外,其他几种情况我们都是知道的,这种情况应该属于流程的一部分,也就是正常的业务逻辑处理流程.我个人认为,不应该使用Exception来处理.
但是,这种设计不能说错,因为设计本来就没有对错,只有优略.我们在这里争论,仅是想说明采用那种设计更加合适.我觉得这个问题,应该这样考虑:
1、个人习惯;
2、程序开发的难易程度;
3、系统的执行效率。
在3不受太大影响的前提下,我觉得,哪种方法均可。应由设计者自行决定。这种问题,没有不会有最终结果的。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics