锁定老帖子 主题:老掉牙的话题,java的异常处理。
精华帖 (1) :: 良好帖 (6) :: 新手帖 (12) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-19
carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 API设计者要求你处理你就要处理
———————————————— 这就回到我上面说的根本理念上了: 这个理念的核心是:API设计者没有资格要求。 看我上面写的这句话: 异常处理的选择权永远在使用方,被使用方不能越俎代庖,被使用方的职责就是要么完成目标要么报告错误,除此以外不要多管闲事。 “这个理念的核心是:API设计者没有资格要求。”恰恰相反,API设计者完全有必要提醒你有非常重要的异常可能会抛出,你一定要处理。 “被使用方的职责就是要么完成目标要么报告错误”这句话有问题,还应包括“要么向上抛出”,就好比我刚才举的IOException。 你凭什么认为我这一层就一定要处理?如果我处理不了怎么办,你的一定是哪来的?说到最后怎么又绕回这里了。这个自以为是的一定是哪来的? 谁设计的API谁当然非常清楚API的实现以及后果,这就是凭据。你处理不了就往上抛,肯定有人处理的了,这已不是导致接口复杂的问题了,是一个重大的错误(分支、环境)必须得处理的问题。 你既然这么说你的一定就不攻自破了。那么你必须要回答checked exception给不能想处理的调用者带来的困扰怎么办? 没有“不能想”,只有“必须得”,因为方法实现者是这么要求的。 我写错了,是不能。看来我还是要怎么说,假设你是某API提供者,你说你可能抛出A,B,C三个异常,如果它们不是checked exception,调用者认为A他可以捕捉,B,C他无法处理,他对于BC不需要被强制做任何动作。这就是这个核心理念:抛出异常者只有告知的权力,没有强制的权力。你不能完全预期你被使用的场景。你的责任只是到你要么完成目标要么抛出异常,你只是说明你可能抛出的异常,你对上层没有强制权力。 程序开发者不能预知场景,但可以预知后果。如果后果很严重,比如我之前提的IOException,oscache 的needsrefrshexception等等,抛出checked exception让调用者重视是很好的设计。当然你用runtimeexception也可以啊,只不过可能调用者会忽视而已。 |
|
返回顶楼 | |
发表时间:2011-03-19
pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 另外我的客户端如果要和server通信那是明确的,你要获得某个server的连接,但是这通常是被配置的,我们先不管这个,假设你获得了server的连接,那么你要和server通信怎么办呢?
连接上提供了足够的通信机制,我们看一下例子: connection.requestRemoteService("服务名", para, new CommonMsgCallback() { public void onMessage(CommonMsg msg) { } connection.requestRemoteService("服务名", para, new CommonMsgSwingCallback() { public void onSwingMessage(CommonMsg msg) { } CommonMsg msg = connection.syncRequestRemoteService("服务名",para); 我想问一下你,在我举得例子里面,你会不知道你在和server通信吗?上面举得三个通信方法都是请求响应模式,其实还有一些变种可以指定这次通信的超时等。第一第二个都是异步的,第二个的好处是如果消息的回应处理需要设置到GUI,那么onSwingMessage已经是EDT线程安全的。 第三个就是同步请求响应。 当然connection还有注册监听模式的通信方式。再我目前构建Swing客户端世界里,我是难以想象一个人最后要通过异常来判断是不是一个耗时的操作。 作为一个大型桌面应用来说,不仅仅与服务器通信这么一个api,更高层次的对象的获取增删改,以及在这之上的各种业务封装非常常见。举个例子吧: City getCityByID(int id)这个方法,如果city是字典库设计(即完全本地内存cache)与非字典库设计(直接远程获取)在方法名上是看不出耗时的,不同过IO Exception提示的话,调用者很可能出EDT问题,特别是其他更加复杂的对象以及对象间的操作及调用封装的话情况更是如此。 别老是用大型这个词,这里你说的问题都是你想屏蔽一些你屏蔽不了的差异带来的。 建议你开发一些这种“大型”应用,体会各种业务逻辑在客户端本地计算导致的EDT痛苦在来本帖也不迟。 是你们自己设计到了这种境地,这种“大型”应用的地步,这样的运作模式。话说我们客户端计算也是很多的。我能想象你们在客户端可能维持大量的强类型的类型体系然后又都是checked exception,可想而知编程有多呆板麻烦。但也是你们自己设计到了这种大象境地。 必须得这样设计。要性能好,一个对象不仅仅有本地二级cache(硬盘),甚至还要有一级cache(内存)。就像浏览器的last modified,第二次刷新贼快的感觉很好滴。 呆板到谈不上,因为本来就是要在EDT外调用的,反而避免了很多程序员的疏忽。 我不是说性能设计上的考量,而是你们本根就没有明确表达出方法的特性,似乎要隐藏什么结果又隐藏不了,还要通过IOException来辨别。其实名称中就完全可以体现出来的。 |
|
返回顶楼 | |
发表时间:2011-03-19
pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 API设计者要求你处理你就要处理
———————————————— 这就回到我上面说的根本理念上了: 这个理念的核心是:API设计者没有资格要求。 看我上面写的这句话: 异常处理的选择权永远在使用方,被使用方不能越俎代庖,被使用方的职责就是要么完成目标要么报告错误,除此以外不要多管闲事。 “这个理念的核心是:API设计者没有资格要求。”恰恰相反,API设计者完全有必要提醒你有非常重要的异常可能会抛出,你一定要处理。 “被使用方的职责就是要么完成目标要么报告错误”这句话有问题,还应包括“要么向上抛出”,就好比我刚才举的IOException。 你凭什么认为我这一层就一定要处理?如果我处理不了怎么办,你的一定是哪来的?说到最后怎么又绕回这里了。这个自以为是的一定是哪来的? 谁设计的API谁当然非常清楚API的实现以及后果,这就是凭据。你处理不了就往上抛,肯定有人处理的了,这已不是导致接口复杂的问题了,是一个重大的错误(分支、环境)必须得处理的问题。 你既然这么说你的一定就不攻自破了。那么你必须要回答checked exception给不能想处理的调用者带来的困扰怎么办? 没有“不能想”,只有“必须得”,因为方法实现者是这么要求的。 我写错了,是不能。看来我还是要怎么说,假设你是某API提供者,你说你可能抛出A,B,C三个异常,如果它们不是checked exception,调用者认为A他可以捕捉,B,C他无法处理,他对于BC不需要被强制做任何动作。这就是这个核心理念:抛出异常者只有告知的权力,没有强制的权力。你不能完全预期你被使用的场景。你的责任只是到你要么完成目标要么抛出异常,你只是说明你可能抛出的异常,你对上层没有强制权力。 程序开发者不能预知场景,但可以预知后果。如果后果很严重,比如我之前提的IOException,oscache 的needsrefrshexception等等,抛出checked exception让调用者重视是很好的设计。当然你用runtimeexception也可以啊,只不过可能调用者会忽视而已。 实践证明调用者只是“被重视”了,导致更多的是乱吞异常。所以说到这里你是不是也明白了,我们真正需要的是什么.需要的是便捷说明机制而非编译强制,我不知道你是否明白了我说的关于异常的权利观。 比如你说严重,你要是这么信誓坦坦,那你直接将系统退出好了,严重不严重还是有场景确定的,我读不到一个配置文件也许本根就是小意思,虽然这是IOException,checked exception一定是违反职责明确的权利观的。 |
|
返回顶楼 | |
发表时间:2011-03-19
carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 另外我的客户端如果要和server通信那是明确的,你要获得某个server的连接,但是这通常是被配置的,我们先不管这个,假设你获得了server的连接,那么你要和server通信怎么办呢?
连接上提供了足够的通信机制,我们看一下例子: connection.requestRemoteService("服务名", para, new CommonMsgCallback() { public void onMessage(CommonMsg msg) { } connection.requestRemoteService("服务名", para, new CommonMsgSwingCallback() { public void onSwingMessage(CommonMsg msg) { } CommonMsg msg = connection.syncRequestRemoteService("服务名",para); 我想问一下你,在我举得例子里面,你会不知道你在和server通信吗?上面举得三个通信方法都是请求响应模式,其实还有一些变种可以指定这次通信的超时等。第一第二个都是异步的,第二个的好处是如果消息的回应处理需要设置到GUI,那么onSwingMessage已经是EDT线程安全的。 第三个就是同步请求响应。 当然connection还有注册监听模式的通信方式。再我目前构建Swing客户端世界里,我是难以想象一个人最后要通过异常来判断是不是一个耗时的操作。 作为一个大型桌面应用来说,不仅仅与服务器通信这么一个api,更高层次的对象的获取增删改,以及在这之上的各种业务封装非常常见。举个例子吧: City getCityByID(int id)这个方法,如果city是字典库设计(即完全本地内存cache)与非字典库设计(直接远程获取)在方法名上是看不出耗时的,不同过IO Exception提示的话,调用者很可能出EDT问题,特别是其他更加复杂的对象以及对象间的操作及调用封装的话情况更是如此。 别老是用大型这个词,这里你说的问题都是你想屏蔽一些你屏蔽不了的差异带来的。 建议你开发一些这种“大型”应用,体会各种业务逻辑在客户端本地计算导致的EDT痛苦在来本帖也不迟。 是你们自己设计到了这种境地,这种“大型”应用的地步,这样的运作模式。话说我们客户端计算也是很多的。我能想象你们在客户端可能维持大量的强类型的类型体系然后又都是checked exception,可想而知编程有多呆板麻烦。但也是你们自己设计到了这种大象境地。 必须得这样设计。要性能好,一个对象不仅仅有本地二级cache(硬盘),甚至还要有一级cache(内存)。就像浏览器的last modified,第二次刷新贼快的感觉很好滴。 呆板到谈不上,因为本来就是要在EDT外调用的,反而避免了很多程序员的疏忽。 我不是说性能设计上的考量,而是你们本根就没有明确表达出方法的特性,似乎要隐藏什么结果又隐藏不了,还要通过IOException来辨别。其实名称中就完全可以体现出来的。 就拿之前的例子来说 getCityByID()本来是本地调用,但由于某种因素把实现改为远程调用了(这种本地改远程的重构可能会很多),那么靠eclipse的重构功能看上去貌似可以搞定,但存在EDT问题。但如果同时将方法加上throws IOException那么,编译器会帮你找出所有的问题存在。 也就是说命名对于EDT安全的帮助往往不那么有效滴。 |
|
返回顶楼 | |
发表时间:2011-03-19
carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 API设计者要求你处理你就要处理
———————————————— 这就回到我上面说的根本理念上了: 这个理念的核心是:API设计者没有资格要求。 看我上面写的这句话: 异常处理的选择权永远在使用方,被使用方不能越俎代庖,被使用方的职责就是要么完成目标要么报告错误,除此以外不要多管闲事。 “这个理念的核心是:API设计者没有资格要求。”恰恰相反,API设计者完全有必要提醒你有非常重要的异常可能会抛出,你一定要处理。 “被使用方的职责就是要么完成目标要么报告错误”这句话有问题,还应包括“要么向上抛出”,就好比我刚才举的IOException。 你凭什么认为我这一层就一定要处理?如果我处理不了怎么办,你的一定是哪来的?说到最后怎么又绕回这里了。这个自以为是的一定是哪来的? 谁设计的API谁当然非常清楚API的实现以及后果,这就是凭据。你处理不了就往上抛,肯定有人处理的了,这已不是导致接口复杂的问题了,是一个重大的错误(分支、环境)必须得处理的问题。 你既然这么说你的一定就不攻自破了。那么你必须要回答checked exception给不能想处理的调用者带来的困扰怎么办? 没有“不能想”,只有“必须得”,因为方法实现者是这么要求的。 我写错了,是不能。看来我还是要怎么说,假设你是某API提供者,你说你可能抛出A,B,C三个异常,如果它们不是checked exception,调用者认为A他可以捕捉,B,C他无法处理,他对于BC不需要被强制做任何动作。这就是这个核心理念:抛出异常者只有告知的权力,没有强制的权力。你不能完全预期你被使用的场景。你的责任只是到你要么完成目标要么抛出异常,你只是说明你可能抛出的异常,你对上层没有强制权力。 程序开发者不能预知场景,但可以预知后果。如果后果很严重,比如我之前提的IOException,oscache 的needsrefrshexception等等,抛出checked exception让调用者重视是很好的设计。当然你用runtimeexception也可以啊,只不过可能调用者会忽视而已。 实践证明调用者只是“被重视”了,导致更多的是乱吞异常。所以说到这里你是不是也明白了,我们真正需要的是什么.需要的是便捷说明机制而非编译强制,我不知道你是否明白了我说的关于异常的权利观。 比如你说严重,你要是这么信誓坦坦,那你直接将系统退出好了,严重不严重还是有场景确定的,我读不到一个配置文件也许本根就是小意思,虽然这是IOException,checked exception一定是违反职责明确的权利观的。 实践?那也得看应用范围。 大部分的web应用都没必要用checked exception,返回错误信息即可,当然有业务异常设计的除外。 桌面我已阐述了IOException的重要性。 其他一些比如金融行业的应用,抛出一个账户操作相关checked exception让调用者捕获往往比什么都重要。。。 |
|
返回顶楼 | |
发表时间:2011-03-19
pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 API设计者要求你处理你就要处理
———————————————— 这就回到我上面说的根本理念上了: 这个理念的核心是:API设计者没有资格要求。 看我上面写的这句话: 异常处理的选择权永远在使用方,被使用方不能越俎代庖,被使用方的职责就是要么完成目标要么报告错误,除此以外不要多管闲事。 “这个理念的核心是:API设计者没有资格要求。”恰恰相反,API设计者完全有必要提醒你有非常重要的异常可能会抛出,你一定要处理。 “被使用方的职责就是要么完成目标要么报告错误”这句话有问题,还应包括“要么向上抛出”,就好比我刚才举的IOException。 你凭什么认为我这一层就一定要处理?如果我处理不了怎么办,你的一定是哪来的?说到最后怎么又绕回这里了。这个自以为是的一定是哪来的? 谁设计的API谁当然非常清楚API的实现以及后果,这就是凭据。你处理不了就往上抛,肯定有人处理的了,这已不是导致接口复杂的问题了,是一个重大的错误(分支、环境)必须得处理的问题。 你既然这么说你的一定就不攻自破了。那么你必须要回答checked exception给不能想处理的调用者带来的困扰怎么办? 没有“不能想”,只有“必须得”,因为方法实现者是这么要求的。 我写错了,是不能。看来我还是要怎么说,假设你是某API提供者,你说你可能抛出A,B,C三个异常,如果它们不是checked exception,调用者认为A他可以捕捉,B,C他无法处理,他对于BC不需要被强制做任何动作。这就是这个核心理念:抛出异常者只有告知的权力,没有强制的权力。你不能完全预期你被使用的场景。你的责任只是到你要么完成目标要么抛出异常,你只是说明你可能抛出的异常,你对上层没有强制权力。 程序开发者不能预知场景,但可以预知后果。如果后果很严重,比如我之前提的IOException,oscache 的needsrefrshexception等等,抛出checked exception让调用者重视是很好的设计。当然你用runtimeexception也可以啊,只不过可能调用者会忽视而已。 实践证明调用者只是“被重视”了,导致更多的是乱吞异常。所以说到这里你是不是也明白了,我们真正需要的是什么.需要的是便捷说明机制而非编译强制,我不知道你是否明白了我说的关于异常的权利观。 比如你说严重,你要是这么信誓坦坦,那你直接将系统退出好了,严重不严重还是有场景确定的,我读不到一个配置文件也许本根就是小意思,虽然这是IOException,checked exception一定是违反职责明确的权利观的。 实践?那也得看应用范围。 大部分的web应用都没必要用checked exception,返回错误信息即可,当然有业务异常设计的除外。 桌面我已阐述了IOException的重要性。 其他一些比如金融行业的应用,抛出一个账户操作相关checked exception让调用者捕获往往比什么都重要。。。 我也是桌面,但我走的路和你本根不同。有很多语言没有checked exception,而且checked exception在很多开源项目上(很多著名的项目上)是越来越少被使用,这些就是重要的实践事实。当年C#的设计者和Java设计者争论这个,时至今日谁赢了,我觉得已经显而易见了。 |
|
返回顶楼 | |
发表时间:2011-03-19
最后修改:2011-03-19
carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 pufan 写道 carlkkx 写道 API设计者要求你处理你就要处理
———————————————— 这就回到我上面说的根本理念上了: 这个理念的核心是:API设计者没有资格要求。 看我上面写的这句话: 异常处理的选择权永远在使用方,被使用方不能越俎代庖,被使用方的职责就是要么完成目标要么报告错误,除此以外不要多管闲事。 “这个理念的核心是:API设计者没有资格要求。”恰恰相反,API设计者完全有必要提醒你有非常重要的异常可能会抛出,你一定要处理。 “被使用方的职责就是要么完成目标要么报告错误”这句话有问题,还应包括“要么向上抛出”,就好比我刚才举的IOException。 你凭什么认为我这一层就一定要处理?如果我处理不了怎么办,你的一定是哪来的?说到最后怎么又绕回这里了。这个自以为是的一定是哪来的? 谁设计的API谁当然非常清楚API的实现以及后果,这就是凭据。你处理不了就往上抛,肯定有人处理的了,这已不是导致接口复杂的问题了,是一个重大的错误(分支、环境)必须得处理的问题。 你既然这么说你的一定就不攻自破了。那么你必须要回答checked exception给不能想处理的调用者带来的困扰怎么办? 没有“不能想”,只有“必须得”,因为方法实现者是这么要求的。 我写错了,是不能。看来我还是要怎么说,假设你是某API提供者,你说你可能抛出A,B,C三个异常,如果它们不是checked exception,调用者认为A他可以捕捉,B,C他无法处理,他对于BC不需要被强制做任何动作。这就是这个核心理念:抛出异常者只有告知的权力,没有强制的权力。你不能完全预期你被使用的场景。你的责任只是到你要么完成目标要么抛出异常,你只是说明你可能抛出的异常,你对上层没有强制权力。 程序开发者不能预知场景,但可以预知后果。如果后果很严重,比如我之前提的IOException,oscache 的needsrefrshexception等等,抛出checked exception让调用者重视是很好的设计。当然你用runtimeexception也可以啊,只不过可能调用者会忽视而已。 实践证明调用者只是“被重视”了,导致更多的是乱吞异常。所以说到这里你是不是也明白了,我们真正需要的是什么.需要的是便捷说明机制而非编译强制,我不知道你是否明白了我说的关于异常的权利观。 比如你说严重,你要是这么信誓坦坦,那你直接将系统退出好了,严重不严重还是有场景确定的,我读不到一个配置文件也许本根就是小意思,虽然这是IOException,checked exception一定是违反职责明确的权利观的。 实践?那也得看应用范围。 大部分的web应用都没必要用checked exception,返回错误信息即可,当然有业务异常设计的除外。 桌面我已阐述了IOException的重要性。 其他一些比如金融行业的应用,抛出一个账户操作相关checked exception让调用者捕获往往比什么都重要。。。 我也是桌面,但我走的路和你本根不同。有很多语言没有checked exception,而且checked exception在很多开源项目上(很多著名的项目上)是越来越少被使用,这些就是重要的实践事实。当年C#的设计者和Java设计者争论这个,时至今日谁赢了,我觉得已经显而易见了。 以前是checked exception过剩,少用只是代表回归正常,重要的一定需要处理的异常毕竟是少的,但决不意味着没有,这就是实践的结果。 至于C#,管它用不用那,个人用java用着很舒服就可以。 |
|
返回顶楼 | |
发表时间:2011-03-19
最后修改:2011-03-19
好好的帖子 就被carlkkx搞的乱七八糟
MS的设计思想是啥? 就是让普通的程序员 通过MSDN的例子就能写出代码 全部都用RuntimeException只不过是对乱吞异常的妥协 但是不能因为妥协了 就说checkedException不好 James Gosling 的设计和层次 是你能理解的了的吗? 对于这213的帖子 没必要再回了 还不如看以前的精华帖 探讨的层次高多了 http://www.iteye.com/topic/2038 |
|
返回顶楼 | |
发表时间:2011-03-19
![]() 发表下个人观点:程序的正确执行只有一条路子,然而出错的路子则有成千上万条。 处理异常貌似应该成为写程序的重中之重。我们也不能一棒子打死CheckException。 回复完鸟 ![]() |
|
返回顶楼 | |
发表时间:2011-03-19
qianhd 写道 好好的帖子 就被carlkkx搞的乱七八糟
MS的设计思想是啥? 就是让普通的程序员 通过MSDN的例子就能写出代码 全部都用RuntimeException只不过是对乱吞异常的妥协 但是不能因为妥协了 就说checkedException不好 James Gosling 的设计和层次 是你能理解的了的吗? 对于这213的帖子 没必要再回了 还不如看以前的精华帖 探讨的层次高多了 http://www.iteye.com/topic/2038 你以为你就了不起了,还看不起别人,你以为在MS平台做开发的人就比你弱?反对checkedException的大牛也有的是,请问这些人的层次又是你能理解的吗? |
|
返回顶楼 | |