论坛首页 Java企业应用论坛

JAVA异常设计原则

浏览 31037 次
精华帖 (7) :: 良好帖 (6) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-01-04   最后修改:2011-01-04
badqiu 写道
不使用异常的人员一直扛着两面大旗:
1. "不要使用异常来控制流程"
2. "性能"

LZ的回答很好,回答了异常最主要的功能:分离错误代码和正常代码,代码更简洁。

但至于 checked exceptin,unchedked exceptin. 你就不要再纠结了,统一使用 RuntimeException. checked exception是JAVA最SB的设计.

1. 它要求调用方强制在调用的位置处理异常. 如SQLException, RMI RemoteException,其实调用方也没有任何办法处理异常,只能log或者再包装一次抛出去. 
2. 影响接口,如果你的接口已经发布出去,如果想增加异常抛出怎么办呢? 使用checked exceptin要影响客户端的代码,编译都过不了. 所以折衷的办法是在接口声明一个所有的父类异常. 如ant的 BuildException.


并且现在的 J2EE规范也基本不使用 checked exception
多数情况下JDK自带的CheckedException,我们都会转化成Unchecked Exception的,如果JDK,如果JDK异常全部都转成Unchecked Exception,异常携带的信息不如我们自己控制更丰富,更灵活。

一些业务异常还是需要CheckException的,程序要根据不同的异常类型返回给用户不同的信息!

比如说,金币不够的异常,你要告诉用户金币不够,还要明确的告诉他现在所以剩多少金币,还需要多少金币,甚至还引导用户到金币充值流程(页面上让用户作出选择),这些都是Unchecked Exception无法做到的。

当然还有另一种解决方案,实现一个金币是否足够的方法! 用哪种实现方法的依据是“金币不够”是属于异常流程还是正常流程。
0 请登录后投票
   发表时间:2011-01-04  
yanical 写道
luckaway 写道

2. 转账的额度是页面单选框(100、200、300、400、500)选择的:
转账的额度用户不能轻易的更改,但是不排除有些无聊的人会借助其他工具(如,firebug)来修改。此类事件还是占少数的,我们就可以把它归结为非软件bug的异常事件—业务异常(Checked Exception)。
正确的实现如下

不错。不过比较疑惑的还是什么时候用Checked Exception,什么时候用Un-Checked Exception。
一直赞同的一个观点是:只有在客户端可以通过某些手段来弥补发生的错误时才使用Checked Exception。
似乎楼主也支持这个观点?但是我一直没有发现过那个地方可以确定客户端可以弥补错误,包括楼主举的上面这个例子,我觉得这个时候客户端也没法做什么了。而且为了这种小可能做成Checked Exception,让调用的地方都要来处理,好像把代码搞混乱了。

改成Unchecked Exception我们只能提示用户“系统错误”之类的,感觉就是软件bug了。

我个人觉得这种事件,还是可以容忍的,应该给用户一个明确的提示,告诉它不要修改radio值
0 请登录后投票
   发表时间:2011-01-04  
现在看的都有些懵了,按我的理解,不管是Exception及其子类或者RuntimeException及其子类,都是有可能对你的业务逻辑产生影响的,如果你非常坚信你的程序不会出错,当然你不用管它是什么异常,但是如果他影响了你的业务逻辑,对用户的体验产生了负面影响,那你就得去解决,当用户访问资源时出现问题,怎么可能不对产生这样的问题的异常进行处理,不能一味的追求代码上的整洁。
0 请登录后投票
   发表时间:2011-01-04   最后修改:2011-01-04
Vicent_Lee 写道
现在看的都有些懵了,按我的理解,不管是Exception及其子类或者RuntimeException及其子类,都是有可能对你的业务逻辑产生影响的,如果你非常坚信你的程序不会出错,当然你不用管它是什么异常,但是如果他影响了你的业务逻辑,对用户的体验产生了负面影响,那你就得去解决,当用户访问资源时出现问题,怎么可能不对产生这样的问题的异常进行处理,不能一味的追求代码上的整洁。


是都用进行处理,不可能把异常抛给用户的!

是如何处理的问题,造成运行时异常的原因有很多,比如;数据库连不上,远程地址访问,数据越界,空指针等,这些根据业务是没什么关系的,不可能根据异常类型一一给出不同的提示。可能就是在Action或者一个统一错误处理类,记录错误的日志,然后提示用户“系统错误,请联系管理员”之类的

对这类异常用户是无能为力的

0 请登录后投票
   发表时间:2011-01-04  
joknm 写道
yanical 写道
不要用异常来控制程序的正常流程


LZ一语道破。
最近也很纠结这个问题。

可我们经常用异常来控制程序的正常流程
0 请登录后投票
   发表时间:2011-01-04  
luckaway 写道
badqiu 写道
不使用异常的人员一直扛着两面大旗:
1. "不要使用异常来控制流程"
2. "性能"

LZ的回答很好,回答了异常最主要的功能:分离错误代码和正常代码,代码更简洁。

但至于 checked exceptin,unchedked exceptin. 你就不要再纠结了,统一使用 RuntimeException. checked exception是JAVA最SB的设计.

1. 它要求调用方强制在调用的位置处理异常. 如SQLException, RMI RemoteException,其实调用方也没有任何办法处理异常,只能log或者再包装一次抛出去. 
2. 影响接口,如果你的接口已经发布出去,如果想增加异常抛出怎么办呢? 使用checked exceptin要影响客户端的代码,编译都过不了. 所以折衷的办法是在接口声明一个所有的父类异常. 如ant的 BuildException.


并且现在的 J2EE规范也基本不使用 checked exception
多数情况下JDK自带的CheckedException,我们都会转化成Unchecked Exception的,如果JDK,如果JDK异常全部都转成Unchecked Exception,异常携带的信息不如我们自己控制更丰富,更灵活。

一些业务异常还是需要CheckException的,程序要根据不同的异常类型返回给用户不同的信息!

比如说,金币不够的异常,你要告诉用户金币不够,还要明确的告诉他现在所以剩多少金币,还需要多少金币,甚至还引导用户到金币充值流程(页面上让用户作出选择),这些都是Unchecked Exception无法做到的。

当然还有另一种解决方案,实现一个金币是否足够的方法! 用哪种实现方法的依据是“金币不够”是属于异常流程还是正常流程。



没搞明白你,难道你 Checked Exception带的信息就比我 UncheckedException信息丰富? 我是说异常体系根本就不需要Checked Exception存在,然后你所要完成的功能全部由 UncheckedException完成。Checked,Unchecked只有在调用处强制处理异常的区别,功能完全是一样的。

举个例子。

我们的servlet要调用你的一个 service方法.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    // 现在我只能抛出 ServletException,IOException,抛不出去SomeCheckedException
    try {
        someService.execute();
    }catch(SomeCheckedException e) {
        // 你竟然要求我立即在这里 处理异常,连给我通过框架统一处理异常的机会都没有,不SB么?
        // 所以,因为CheckdException,我在这里只能 log一次,或者是 throw new RuntimeException(e);
    }
}


0 请登录后投票
   发表时间:2011-01-04  
badqiu 写道
luckaway 写道
badqiu 写道
不使用异常的人员一直扛着两面大旗:
1. "不要使用异常来控制流程"
2. "性能"

LZ的回答很好,回答了异常最主要的功能:分离错误代码和正常代码,代码更简洁。

但至于 checked exceptin,unchedked exceptin. 你就不要再纠结了,统一使用 RuntimeException. checked exception是JAVA最SB的设计.

1. 它要求调用方强制在调用的位置处理异常. 如SQLException, RMI RemoteException,其实调用方也没有任何办法处理异常,只能log或者再包装一次抛出去. 
2. 影响接口,如果你的接口已经发布出去,如果想增加异常抛出怎么办呢? 使用checked exceptin要影响客户端的代码,编译都过不了. 所以折衷的办法是在接口声明一个所有的父类异常. 如ant的 BuildException.


并且现在的 J2EE规范也基本不使用 checked exception
多数情况下JDK自带的CheckedException,我们都会转化成Unchecked Exception的,如果JDK,如果JDK异常全部都转成Unchecked Exception,异常携带的信息不如我们自己控制更丰富,更灵活。

一些业务异常还是需要CheckException的,程序要根据不同的异常类型返回给用户不同的信息!

比如说,金币不够的异常,你要告诉用户金币不够,还要明确的告诉他现在所以剩多少金币,还需要多少金币,甚至还引导用户到金币充值流程(页面上让用户作出选择),这些都是Unchecked Exception无法做到的。

当然还有另一种解决方案,实现一个金币是否足够的方法! 用哪种实现方法的依据是“金币不够”是属于异常流程还是正常流程。



没搞明白你,难道你 Checked Exception带的信息就比我 UncheckedException信息丰富? 我是说异常体系根本就不需要Checked Exception存在,然后你所要完成的功能全部由 UncheckedException完成。Checked,Unchecked只有在调用处强制处理异常的区别,功能完全是一样的。

举个例子。

我们的servlet要调用你的一个 service方法.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    // 现在我只能抛出 ServletException,IOException,抛不出去SomeCheckedException
    try {
        someService.execute();
    }catch(SomeCheckedException e) {
        // 你竟然要求我立即在这里 处理异常,连给我通过框架统一处理异常的机会都没有,不SB么?
        // 所以,因为CheckdException,我在这里只能 log一次,或者是 throw new RuntimeException(e);
    }
}




这个可以在service层就把异常都处理掉吧。如果这个checked的异常是很无聊的一个异常的话只能说是设计上面的问题,不能说是checked异常的问题。checked异常的用处不就是告诉你我这里可能会出错么,如果都是runtime的话对于其他人连你可能会有哪些异常都不知道啊。
0 请登录后投票
   发表时间:2011-01-04  
badqiu 写道

没搞明白你,难道你 Checked Exception带的信息就比我 UncheckedException信息丰富? 我是说异常体系根本就不需要Checked Exception存在,然后你所要完成的功能全部由 UncheckedException完成。Checked,Unchecked只有在调用处强制处理异常的区别,功能完全是一样的。

举个例子。

我们的servlet要调用你的一个 service方法.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    // 现在我只能抛出 ServletException,IOException,抛不出去SomeCheckedException
    try {
        someService.execute();
    }catch(SomeCheckedException e) {
        // 你竟然要求我立即在这里 处理异常,连给我通过框架统一处理异常的机会都没有,不SB么?
        // 所以,因为CheckdException,我在这里只能 log一次,或者是 throw new RuntimeException(e);
    }
}



如果仅仅是记录错误日志或者throw new RuntimeException(e),是没必用Checked Exception。JDK的Checked Exception,如:SqlException、UnsupportedEncodingException ,我们都是简单的封装成runtime Exception,也不会增加额外的信息,这种场景下,确实不应该是Checked Exception。


Unchecked Exception和Checked Exception都能携带信息,Unchecked Exception里携带的信息只会给日志记录用。
Checked Exception携带信息更多的作用是给用户看的,甚至有可能都不记录日志了。

public String execute() {
	try {
		userService.transferCoin(coin);
	} catch (CoinNotEnoughException e) {
		context.put("errorMessage", "你目前的金币是" + e.getTotalCoin() + ",无法转账" + e.getForTransferCoin());
	}
	return SUCCESS;
}
0 请登录后投票
   发表时间:2011-01-04   最后修改:2011-01-04
luckaway 写道
badqiu 写道

没搞明白你,难道你 Checked Exception带的信息就比我 UncheckedException信息丰富? 我是说异常体系根本就不需要Checked Exception存在,然后你所要完成的功能全部由 UncheckedException完成。Checked,Unchecked只有在调用处强制处理异常的区别,功能完全是一样的。

举个例子。

我们的servlet要调用你的一个 service方法.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    // 现在我只能抛出 ServletException,IOException,抛不出去SomeCheckedException
    try {
        someService.execute();
    }catch(SomeCheckedException e) {
        // 你竟然要求我立即在这里 处理异常,连给我通过框架统一处理异常的机会都没有,不SB么?
        // 所以,因为CheckdException,我在这里只能 log一次,或者是 throw new RuntimeException(e);
    }
}



如果仅仅是记录错误日志或者throw new RuntimeException(e),是没必用Checked Exception。JDK的Checked Exception,如:SqlException、UnsupportedEncodingException ,我们都是简单的封装成runtime Exception,也不会增加额外的信息,这种场景下,确实不应该是Checked Exception。


Unchecked Exception和Checked Exception都能携带信息,Unchecked Exception里携带的信息只会给日志记录用。
Checked Exception携带信息更多的作用是给用户看的,甚至有可能都不记录日志了。

public String execute() {
	try {
		userService.transferCoin(coin);
	} catch (CoinNotEnoughException e) {
		context.put("errorMessage", "你目前的金币是" + e.getTotalCoin() + ",无法转账" + e.getForTransferCoin());
	}
	return SUCCESS;
}



如你自己的demo,你的调用方一定需要强制处理该异常了。 已经没有办法使用框架来处理异常。

你的Checked Exception只是你自己一厢情愿的认为按你现在的方式处理。
难道其它语言没有 Checked Exception就不用活了。 硬按你这种规则区分。

SqlException,UnsupportedEncodingException, DateFormat ParseException 都是JDK败笔,已经懒得说了。


我一直所说使用Checked Exception最主要的缺点: 接口污染,强制调用者立即处理。
所以不用跟我说 Exception转换为message的程序了. 因为要转换为消息的时候,我也直接处理CoinNotEnoughException 这个RuntimeException. 而不是Checked Exception
0 请登录后投票
   发表时间:2011-01-04  
joknm 写道
yanical 写道
不要用异常来控制程序的正常流程


LZ一语道破。
最近也很纠结这个问题。

我一般是用来控制业务流程
0 请登录后投票
论坛首页 Java企业应用版

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