J2EE项目异常处理
- public String getPassword(String userId)throws DataAccessException{
- String sql = “select password from userinfo where userid=’”+userId +”’”;
- String password = null;
- Connection con = null;
- Statement s = null;
- ResultSet rs = null;
- try{
- con = getConnection();//获得数据连接
- s = con.createStatement();
- rs = s.executeQuery(sql);
- while(rs.next()){
- password = rs.getString(1);
- }
- rs.close();
- s.close();
- }
- Catch(SqlException ex){
- throw new DataAccessException(ex);
- }
- finally{
- try{
- if(con != null){
- con.close();
- }
- }
- Catch(SQLException sqlEx){
- throw new DataAccessException(“关闭连接失败!”,sqlEx);
- }
- }
- return password;
- }
- public String getPassword(String userId){
- try{
- ……
- Statement s = con.createStatement();
- ……
- Catch(SQLException sqlEx){
- ……
- }
- ……
- }
- public String getPassword(String userId)throws SQLException{
- Statement s = con.createStatement();
- }
- String str = “123”;
- int value = Integer.parseInt(str);
- public static int parseInt(String s) throws NumberFormatException
- try{
- ……
- Statement s = con.createStatement();
- ……
- Catch(SQLException sqlEx){
- sqlEx.PrintStackTrace();
- }
- 或者
- try{
- ……
- Statement s = con.createStatement();
- ……
- Catch(SQLException sqlEx){
- //什么也不干
- }
- public void methodA()throws ExceptionA{
- …..
- throw new ExceptionA();
- }
- public void methodB()throws ExceptionB{
- try{
- methodA();
- ……
- }catch(ExceptionA ex){
- throw new ExceptionB(ex);
- }
- }
- Public void methodC()throws ExceptinC{
- try{
- methodB();
- …
- }
- catch(ExceptionB ex){
- throw new ExceptionC(ex);
- }
- }
如java 代码
- IllegalArgumentException, UnsupportedOperationException
- public void methodA()throws ExceptionA{
- …..
- throw new ExceptionA();
- }
- public void methodB()throws ExceptionB{
- try{
- methodA();
- ……
- }catch(ExceptionA ex){
- throw new ExceptionB(ex);
- }
- }
- public Class ExceptionB extends Exception{
- private Throwable cause;
- public ExceptionB(String msg, Throwable ex){
- super(msg);
- this.cause = ex;
- }
- public ExceptionB(String msg){
- super(msg);
- }
- public ExceptionB(Throwable ex){
- this.cause = ex;
- }
- }
- public void printStackTrace(PrintStrean ps){
- if(cause == null){
- super.printStackTrace(ps);
- }else{
- ps.println(this);
- cause.printStackTrace(ps);
- }
- }
- public NestedException extends Exception{
- private Throwable cause;
- public NestedException (String msg){
- super(msg);
- }
- public NestedException(String msg, Throwable ex){
- super(msg);
- This.cause = ex;
- }
- public Throwable getCause(){
- return (this.cause == null ? this :this.cause);
- }
- public getMessage(){
- String message = super.getMessage();
- Throwable cause = getCause();
- if(cause != null){
- message = message + “;nested Exception is ” + cause;
- }
- return message;
- }
- public void printStackTrace(PrintStream ps){
- if(getCause == null){
- super.printStackTrace(ps);
- }else{
- ps.println(this);
- getCause().printStackTrace(ps);
- }
- }
- public void printStackTrace(PrintWrite pw){
- if(getCause() == null){
- super.printStackTrace(pw);
- }
- else{
- pw.println(this);
- getCause().printStackTrace(pw);
- }
- }
- public void printStackTrace(){
- printStackTrace(System.error);
- }
- }
- public String getPassword(String userId)throws NoSuchUserException{
- UserInfo user = userDao.queryUserById(userId);
- If(user == null){
- Logger.info(“找不到该用户信息,userId=”+userId);
- throw new NoSuchUserException(“找不到该用户信息,userId=”+userId);
- }
- else{
- return user.getPassword();
- }
- }
- public void sendUserPassword(String userId)throws Exception {
- UserInfo user = null;
- try{
- user = getPassword(userId);
- //……..
- sendMail();
- //
- }catch(NoSuchUserException ex)(
- logger.error(“找不到该用户信息:”+userId+ex);
- throw new Exception(ex);
- }
- public Date getDate(String str){
- Date applyDate = null;
- SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
- try{
- applyDate = format.parse(applyDateStr);
- }
- catch(ParseException ex){
- //乎略,当格式错误时,返回null
- }
- return applyDate;
- }
- try{
- ……
- String sql=”select * from userinfo”;
- Statement s = con.createStatement();
- ……
- Catch(SQLException sqlEx){
- Logger.error(“sql执行错误”+sql+sqlEx);
- }
- public class BusinessException extends Exception {
- private void logTrace() {
- StringBuffer buffer=new StringBuffer();
- buffer.append("Business Error in Class: ");
- buffer.append(getClassName());
- buffer.append(",method: ");
- buffer.append(getMethodName());
- buffer.append(",messsage: ");
- buffer.append(this.getMessage());
- logger.error(buffer.toString());
- }
- public BusinessException(String s) {
- super(s);
- race();
- }
- //
- public class UserSoaImpl implements UserSoa{
- public UserInfo getUserInfo(String userId)throws RemoteException{
- //……
- 远程方法调用.
- //……
- }
- }
- public interface UserManager{
- public UserInfo getUserInfo(Stirng userId)throws RemoteException;
- }
- public DataAccessException extends RuntimeException{
- ……
- }
- public interface UserDao{
- public String getPassword(String userId)throws DataAccessException;
- }
- public class UserDaoImpl implements UserDAO{
- public String getPassword(String userId)throws DataAccessException{
- String sql = “select password from userInfo where userId= ‘”+userId+”’”;
- try{
- …
- //JDBC调用
- s.executeQuery(sql);
- …
- }catch(SQLException ex){
- throw new DataAccessException(“数据库查询失败”+sql,ex);
- }
- }
- }
- public class BusinessException extends Exception{
- …..
- }
- public interface UserManager{
- public Userinfo copyUserInfo(Userinfo user)throws BusinessException{
- Userinfo newUser = null;
- try{
- newUser = (Userinfo)user.clone();
- }catch(CloneNotSupportedException ex){
- throw new BusinessException(“不支持clone方法:”+Userinfo.class.getName(),ex);
- }
- }
- }
- ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception{
- String ageStr = request.getParameter(“age”);
- int age = Integer.parse(ageStr);
- …………
- String birthDayStr = request.getParameter(“birthDay”);
- SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
- Date birthDay = format.parse(birthDayStr);
- }
- ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception{
- String ageStr = request.getParameter(“age”);
- String birthDayStr = request.getParameter(“birthDay”);
- int age = 0;
- Date birthDay = null;
- try{
- age=Integer.parse(ageStr);
- }catch(NumberFormatException ex){
- error.reject(“age”,”不是合法的整数值”);
- }
- …………
- try{
- SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
- birthDay = format.parse(birthDayStr);
- }catch(ParseException ex){
- error.reject(“birthDay”,”不是合法的日期,请录入’MM/dd/yyy’格式的日期”);
- }
- }
评论
一般地,我们需要定义一个unChecked异常,让集成层接口的所有方法都声明抛出这unChecked异常。
java 代码
public DataAccessException extends RuntimeException{
……
}
public interface UserDao{
public String getPassword(String userId)throws DataAccessException;
}
public class UserDaoImpl implements UserDAO{
public String getPassword(String userId)throws DataAccessException{
String sql = “select password from userInfo where userId= ‘”+userId+”’”;
try{
…
//JDBC调用
s.executeQuery(sql);
…
}catch(SQLException ex){
throw new DataAccessException(“数据库查询失败”+sql,ex);
}
}
}
定义一个checked的业务异常,让业务层的接口的所有方法都声明抛出unChecked异常.
java 代码
public class BusinessException extends Exception{
…..
}
public interface UserManager{
public Userinfo copyUserInfo(Userinfo user)throws BusinessException{
Userinfo newUser = null;
try{
newUser = (Userinfo)user.clone();
}catch(CloneNotSupportedException ex){
throw new BusinessException(“不支持clone方法:”+Userinfo.class.getName(),ex);
}
}
}
不好意思,两个问题
1) 接口UserDao应该可以把throws DataAccessException 拿掉
2) 定义一个checked的业务异常,让业务层的接口的所有方法都声明抛出unChecked异常.
这句话对么?定义了BusinessException这个checked异常,public Userinfo copyUserInfo(Userinfo user)throws BusinessException,让业务层的接口的所有方法都声明抛出unChecked异常怎么理解?
望指教
1)那是不对滴。为什么要让Dao抛出unChecked异常呢?就是进行一次封装!让上层调用者自己决定处理dao的异常
2)如果让业务方法都抛出unChecked异常,业务方法是我们最关心的。最需要去处理的。所以强制处理
1/ 根据系统的分层,每层自定义一个unchecked exception, exception里面只包含简单的message信息即可, 这样每层实现时,只需要抛出本层定义的exception并提供信息就可以了;
2/ 还是根据系统分层,高层在调用底层的api时,一定要捕获底层定义的这个exception(不过推荐是catch Exception()),并根据本层的logic决定是继续抛出本层的exception还是进行其他处理;
3/ 提供一个util方法可以拿到root exception的message,这样可以保证即使进行多次包装后,也能得到最初抛出exception的信息;
4/ checked exception能不用就不用,除非有业务逻辑需要通过exception来实现不同的流程(这种情况通常也是可以避免的),还有就是涉及到资源的情况,有可能必须使用checked exception,不过一般来说,这种情况都可以限制在本层内部,通过catch and rethrow我们自定义的异常来解决,只是需要注意在finally里面把资源释放掉.
曾经使用别人提供的api,里面会抛出一个自定义checked exception,可是我这边的logic非常复杂,涉及到3到4层的调用,如果每层都try catch的话....最终只能将这个checked exception包装成一个unchecked exception...世界清净了
一般来说,不管是抛出何种异常,就代表logic已经发生错误,而且基本不太可能恢复,所以checked exception用处真的不大.
个人观点,欢迎大家讨论.
一般地,我们需要定义一个unChecked异常,让集成层接口的所有方法都声明抛出这unChecked异常。
java 代码
public DataAccessException extends RuntimeException{
……
}
public interface UserDao{
public String getPassword(String userId)throws DataAccessException;
}
public class UserDaoImpl implements UserDAO{
public String getPassword(String userId)throws DataAccessException{
String sql = “select password from userInfo where userId= ‘”+userId+”’”;
try{
…
//JDBC调用
s.executeQuery(sql);
…
}catch(SQLException ex){
throw new DataAccessException(“数据库查询失败”+sql,ex);
}
}
}
定义一个checked的业务异常,让业务层的接口的所有方法都声明抛出unChecked异常.
java 代码
public class BusinessException extends Exception{
…..
}
public interface UserManager{
public Userinfo copyUserInfo(Userinfo user)throws BusinessException{
Userinfo newUser = null;
try{
newUser = (Userinfo)user.clone();
}catch(CloneNotSupportedException ex){
throw new BusinessException(“不支持clone方法:”+Userinfo.class.getName(),ex);
}
}
}
不好意思,两个问题
1) 接口UserDao应该可以把throws DataAccessException 拿掉
2) 定义一个checked的业务异常,让业务层的接口的所有方法都声明抛出unChecked异常.
这句话对么?定义了BusinessException这个checked异常,public Userinfo copyUserInfo(Userinfo user)throws BusinessException,让业务层的接口的所有方法都声明抛出unChecked异常怎么理解?
望指教
返回值,这没有什么难以理解的啦!!
当方法出现几种逻辑时,有时用方法的返回值无法描述,这时可以用一个异常信息来代表返回结果!
唉,可能我还是没有说清楚!!我得去翻以前的程序,把例子弄出来
这种做法应该尽量避免,最近项目组里写一个根据将xml文件导入数据库,在导入之前需要验证xml的合法性,当xml不合法的时候,想告诉用户一个比较详细的信息:比如在哪行哪列出错了,就将这些信息写入异常中抛出来,这算是一个返回结果吧,勉强可以接受,大概这样:
try{
check();
import();
forward(sucess);
}catch(Exception,e){
forward(error,e)
}
一般情况是不会这样做的!!!
我遇到这样的一个需求!
项目之间的关系有三种:前,后,无。
需要判断所有的项目间不能存在循环路径
a -> b->c->a
这就是循环路径了!
我用一个图实现检查是否存在循环路径,并且需要记录下这个循环路径。
需求仅要找出第一个循环路径即可,就不用往下找了
思路:从任一个点出发,如果找到它邻节点为第一个出发点时,那么就是循环路径。
当然是使用递归来实现的,因为需要记录循环的路径,所以比较麻烦的。一开始我是使用返回值!
这样它会记录的路径其实是一个倒置的路径。但中间还会出很多问题,这点我就不详细说了!
后来我干脆采用异常的方式来处理。
从任意一点往下找,当任一节点的邻节点为第第一个出发点时,我就抛出异常
if(vertexIndex == firstVertexIndex){
throw new CycleException("存在环路!");
}
这也是最不可能出错和效率最高的方法了!
上级调用代码
try {
recordList.add(this.vertexList.get(vertexIndex));
int nextVertex = findHasNextVertex(vertexIndex,vertexIndex,recordList);
}
catch(CycleException ex) {
return recordList;
}
但是千万不要学这种方式!
这有时是不得已而为之的!
不讨论异常处理的方式。
有向图存在环不是这么检查的吧?
每次搜索 从任一初始点出发,广度搜索,只要访问到访问过得点就认为存在环。
我这里只是一点点代码,我不可能把所有的贴出来吧!!!!
深度还是广度遍历都是可以的嘛!
没看过中文版,j2ee design and development E版里面有比较详细的说明,
返回值,这没有什么难以理解的啦!!
当方法出现几种逻辑时,有时用方法的返回值无法描述,这时可以用一个异常信息来代表返回结果!
唉,可能我还是没有说清楚!!我得去翻以前的程序,把例子弄出来
这种做法应该尽量避免,最近项目组里写一个根据将xml文件导入数据库,在导入之前需要验证xml的合法性,当xml不合法的时候,想告诉用户一个比较详细的信息:比如在哪行哪列出错了,就将这些信息写入异常中抛出来,这算是一个返回结果吧,勉强可以接受,大概这样:
try{
check();
import();
forward(sucess);
}catch(Exception,e){
forward(error,e)
}
一般情况是不会这样做的!!!
我遇到这样的一个需求!
项目之间的关系有三种:前,后,无。
需要判断所有的项目间不能存在循环路径
a -> b->c->a
这就是循环路径了!
我用一个图实现检查是否存在循环路径,并且需要记录下这个循环路径。
需求仅要找出第一个循环路径即可,就不用往下找了
思路:从任一个点出发,如果找到它邻节点为第一个出发点时,那么就是循环路径。
当然是使用递归来实现的,因为需要记录循环的路径,所以比较麻烦的。一开始我是使用返回值!
这样它会记录的路径其实是一个倒置的路径。但中间还会出很多问题,这点我就不详细说了!
后来我干脆采用异常的方式来处理。
从任意一点往下找,当任一节点的邻节点为第第一个出发点时,我就抛出异常
if(vertexIndex == firstVertexIndex){
throw new CycleException("存在环路!");
}
这也是最不可能出错和效率最高的方法了!
上级调用代码
try {
recordList.add(this.vertexList.get(vertexIndex));
int nextVertex = findHasNextVertex(vertexIndex,vertexIndex,recordList);
}
catch(CycleException ex) {
return recordList;
}
但是千万不要学这种方式!
这有时是不得已而为之的!
不讨论异常处理的方式。
有向图存在环不是这么检查的吧?
每次搜索 从任一初始点出发,广度搜索,只要访问到访问过得点就认为存在环。
javastudy 写道:
返回值,这没有什么难以理解的啦!!
当方法出现几种逻辑时,有时用方法的返回值无法描述,这时可以用一个异常信息来代表返回结果!
唉,可能我还是没有说清楚!!我得去翻以前的程序,把例子弄出来
这种做法应该尽量避免,最近项目组里写一个根据将xml文件导入数据库,在导入之前需要验证xml的合法性,当xml不合法的时候,想告诉用户一个比较详细的信息:比如在哪行哪列出错了,就将这些信息写入异常中抛出来,这算是一个返回结果吧,勉强可以接受,大概这样:
try{
check();
import();
forward(sucess);
}catch(Exception,e){
forward(error,e)
}
一般情况是不会这样做的!!!
我遇到这样的一个需求!
项目之间的关系有三种:前,后,无。
需要判断所有的项目间不能存在循环路径
a -> b->c->a
这就是循环路径了!
我用一个图实现检查是否存在循环路径,并且需要记录下这个循环路径。
需求仅要找出第一个循环路径即可,就不用往下找了
思路:从任一个点出发,如果找到它邻节点为第一个出发点时,那么就是循环路径。
当然是使用递归来实现的,因为需要记录循环的路径,所以比较麻烦的。一开始我是使用返回值!
这样它会记录的路径其实是一个倒置的路径。但中间还会出很多问题,这点我就不详细说了!
后来我干脆采用异常的方式来处理。
从任意一点往下找,当任一节点的邻节点为第第一个出发点时,我就抛出异常
if(vertexIndex == firstVertexIndex){
throw new CycleException("存在环路!");
}
这也是最不可能出错和效率最高的方法了!
上级调用代码
try {
recordList.add(this.vertexList.get(vertexIndex));
int nextVertex = findHasNextVertex(vertexIndex,vertexIndex,recordList);
}
catch(CycleException ex) {
return recordList;
}
但是千万不要学这种方式!
这有时是不得已而为之的!
减少恶心的try catch 块。。。。
(这样用checked的理由又多了一点点)
这怎么就成为了checked的理由呢?如果用Spring,也就是说异常交由Spring来处理,方法调用更不用知道有异常的存在了,unchecked不是更好么。透明到底
事实上spring的用法都是unchecked
但是我还是认为spring 能带来checked的用法变革
这也不竟然吧!!只有严重的错误才会抛unchecked异常!
减少恶心的try catch 块。。。。
(这样用checked的理由又多了一点点)
这怎么就成为了checked的理由呢?如果用Spring,也就是说异常交由Spring来处理,方法调用更不用知道有异常的存在了,unchecked不是更好么。透明到底
事实上spring的用法都是unchecked
但是我还是认为spring 能带来checked的用法变革
能说一下原因么?实在不理解
返回值,这没有什么难以理解的啦!!
当方法出现几种逻辑时,有时用方法的返回值无法描述,这时可以用一个异常信息来代表返回结果!
唉,可能我还是没有说清楚!!我得去翻以前的程序,把例子弄出来
这种做法应该尽量避免,最近项目组里写一个根据将xml文件导入数据库,在导入之前需要验证xml的合法性,当xml不合法的时候,想告诉用户一个比较详细的信息:比如在哪行哪列出错了,就将这些信息写入异常中抛出来,这算是一个返回结果吧,勉强可以接受,大概这样:
try{
check();
import();
forward(sucess);
}catch(Exception,e){
forward(error,e)
}
减少恶心的try catch 块。。。。
(这样用checked的理由又多了一点点)
这怎么就成为了checked的理由呢?如果用Spring,也就是说异常交由Spring来处理,方法调用更不用知道有异常的存在了,unchecked不是更好么。透明到底
事实上spring的用法都是unchecked
但是我还是认为spring 能带来checked的用法变革
减少恶心的try catch 块。。。。
(这样用checked的理由又多了一点点)
这怎么就成为了checked的理由呢?如果用Spring,也就是说异常交由Spring来处理,方法调用更不用知道有异常的存在了,unchecked不是更好么。透明到底
最近刚好作了一个产品的异常处理规范,把我做的也拿出来晒晒,和大家讨论一下。
1、CheckException or UnCheckedException
个人倾向用UnCheckedException。我见过的最多的处理异常的代码就是记录日志或转换后抛出
,好像做其他操作的少之又少。我以前还见过有人不管三七二十一,抓到什么抛什么,结果一个接口抛出了3-5种CheckException。别扭啊,呵呵。
当然,最大的缺陷就是对接口调用者的使用。至少UnCheckedException可以让接口调用者选择catch还是不catch。
因为这是一个遗留系统,都使用了CheckedException,不过好在使用的比较规范,没有太大麻烦。
2、异常信息
因为开发者众多,异常信息五花八门,有中文的有英文的,有简单的,有复杂的。散落在各个类里,修改起来很麻烦。
我的处理办法是,定义异常码,异常信息和异常码一一对应,定义在properties文件里,抛出异常的地方只引用异常码。这样,如果需要修改异常信息,只要修改properties文件重新打包即可。异常码分为原因码和位置码。位置码一般用在业务逻辑类里。比如一般用到的Facad模式,可能一个接口定义了n个方法,每个方法都抛出XXXBusinessException(XXX用于区分业务子包),抛出的异常码在代码里顺序定义即可。原因码表示某类异常,比如SQLException引起的异常都为8000。
异常码中原因码按包、类、接口定义,比如:前两位表示一级子包,接下来两位留给二级子包,接下来两位表示类,最后3位表示方法。
异常信息如果需要,可以保留现场信息。比如:“用户[abc]已存在”。这样的信息就比“用户已存在”明确。这个功能可以通过java.text.MessageFormat实现。
3、异常的链式抛出
即,在调用底层接口时捕获到异常,需要转成其他的异常抛出时,使用带Throwable的构造器。这样可以保留最原始的出错信息。
异常基类代码:
- public class BaseException extends Exception {
- protected long errorCode;
- protected String[] args;
- /**
- * @param errorCode
- */
- public BaseException(long errorCode) {
- super();
- this.errorCode = errorCode;
- }
- /**
- * @param errorCode
- * @param cause
- */
- public BaseException(long errorCode,Throwable cause) {
- super(cause);
- this.errorCode = errorCode;
- }
- /**
- * @param errorCode
- * @param cause
- * @param args @see {@link java.text.MessageFormat#format(Object)}
- */
- public BaseException(long errorCode,Throwable cause,String[] args) {
- super(cause);
- this.errorCode = errorCode;
- this.args = args;
- }
- /* (non-Javadoc)
- * @see java.lang.Throwable#getMessage()
- */
- public String getMessage() {
- String message = "";
- if (this.args == null || this.args.length == 0) {
- message = MessageSource.getInstance().resolveCodeWithoutArguments(
- this.errorCode);
- } else {
- message = MessageSource.getInstance().resolveCode(this.errorCode)
- .format(this.args);
- }
- return this.errorCode+":"+message;
- }
- /**
- * @return the errorCode
- */
- public long getErrorCode() {
- return errorCode;
- }
- /**
- * @return the args
- */
- public String[] getArgs() {
- return args;
- }
- }
其中:MessageSource这个类就是根据是否有现场信息,分别处理,得到完整异常信息表述字符串。
关于主贴中嵌套打印的部分,从JDK1.4开始,Throwable就是嵌套打印的,所以不必再覆盖那几个方法了。
现在假使,有AException 和BException,都从BaseException继承。在方法里,我们捕获了AException,需要转换成BException抛出,这时候我们就非常希望能直接用AException的信息(errorCode和args)。所以,如果再来这样一个构造器似乎更好:
- public BaseException(BaseException cause){
- this.errorCode = cause.getErrorCode();
- this.args = cause.getArgs();
- }
但是,因为Exception有一个构造器:public Exception(Throwable cause),所以这样的构造器就是重载(overload),而不是覆盖(Override)。重载,入参又是父子类关系,这样的方法很容易混淆,所以就没有提供。
我按照这个异常处理规范,花了两三天时间把代码重构了一遍。似乎用起来挺好使
正想问有什么东西说错呢。
我一直想不出怎么简化这文章了!!
正想问有什么东西说错呢。
汗。。。返回值?你的意思可以理解但,语法有问题,并且要加上非常 用返回值。。。
返回值,这没有什么难以理解的啦!!
当方法出现几种逻辑时,有时用方法的返回值无法描述,这时可以用一个异常信息来代表返回结果!
唉,可能我还是没有说清楚!!我得去翻以前的程序,把例子弄出来
第四第五也不错但想不到怎么用很少的语言表术出来。
由于很多好的文章由于太长不很被人了解,所以作了一个简化版 ,
用以吸引读者,扩大讨论。
这的确也是,很多人难以一次读完
如果对异常有一定的规律性可以用spring来作异常处理,
减少恶心的try catch 块。。。。
(这样用checked的理由又多了一点点)
如果一个异常是可以恢复的,可以被调用者正确处理的,使用checked异常。
在使用unChecked异常时,必须在在方法声明中详细的说明该方法可能会抛出的unChekced异常。由调用者自己去决定是否捕获unChecked异常
仔细看了后本贴非常不错。
当所有调用者必须处理这个异常,可以让调用者进行重试操作;或者该异常相当于该方法的第二个返回值。使用checked异常。
汗。。。返回值?你的意思可以理解但,语法有问题,并且要加上非常 用返回值。。。
代码就不拷贝了,非常的精典用法。
第四第五也不错但想不到怎么用很少的语言表术出来。
由于很多好的文章由于太长不很被人了解,所以作了一个简化版 ,
用以吸引读者,扩大讨论。
try{}catch{}finally{}就完事了
至于是什么类型的异常,其实不必关心
楼上的要是这么说就不对了,要知其然,知其所以然嘛!
- 浏览: 93215 次

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
Oracle 数据类型及存储方 ...
第六部分 ROWID ROWID 就是数据库中一行的地址,用于记录数据存储的一 ...
-- by klyuan -
Oracle 数据类型及存储方 ...
第五部分 LONG类型 LONG是一种已经被弃用的数据类型,LOB类型是它的替代 ...
-- by klyuan -
Oracle 数据类型及存储方 ...
第四部分 LOB类型 § 4.1 LOB类型 4.1.1 LOB类型分类 C ...
-- by klyuan -
Oracle 数据类型及存储方 ...
第三部分 日期时间类型 §3.1 DATE Date类型Oralce用于表示日 ...
-- by klyuan -
Oracle 数据类型及存储方 ...
第二部分 数值类型 § 2.1 number Number类型是oralce的 ...
-- by klyuan






评论排行榜