- 浏览: 2675527 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
我素熊猫:
66666666666666
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderL -
jonyzhou94:
1987_ming 写道1987_ming 写道System. ...
CXF框架入门实例 -
davidforit:
你那个“2004年Nutch创始人Doug Cutting基于 ...
《Hadoop基础教程》之初识Hadoop -
masuweng:
我的就是这么弄得,到了页面还是那个格式的 。
JSONObject转换JSON--将Date转换为指定格式 -
masuweng:
∑
JSONObject转换JSON--将Date转换为指定格式
从学习到现在从事java开发一年多了,个人觉得对java只了解皮毛,很多东西都是用到再去慢慢学习,编程真的是一项艺术,要完成一段好的代码,需要懂得很多。
最近项目经理让我负责一个组件开发,框架都由自己搭建,最让我头疼的是异常处理,我看了一些网上的源码,发现他们对异常的处理不是很重视,研究了很久都没有找到很好的解决方案。后来有幸看到一个200W美元的项目部分源码,通过他们对异常处理的解决方案,我终于弄通了java异常的一些基本机制,在这与大家分享一下。
(一)说到异常,首先从Throwable开始,Throwable是所有异常的基类,旗下有Error和Exception两个子类:Error属于程序无法控制的错误,通常不推荐捕获,捕获了你也处理不了;Exception就是我们熟知的可控制异常了。Exception旗下又分两种异常,运行时异常(RuntimeException)和非运行时异常:运行时异常是不需要强制捕获的,因为它随时随地可能发生,比如空指针异常(NullPointerException)和数组下标越界(IndexOutOfBoundsException);而非运行时异常在java里是需要你最终捕获的,不然编译都不通过,比如IO异常(IOException)和数据库错误(SqlException)。
下面来个例子:
①运行时异常数组下标越界(IndexOutOfBoundsException):
public class RuntimeDemo { public static void main(String[] args) { List<String> lst = new ArrayList<String>(); lst.add("1"); System.out.println(lst.get(10)); } }
上面代码list里只有1条数据,但是我希望获取第11条数据,肯定会报异常的,但是我不需要捕获异常,因为结果是运行是异常,它会自动抛出异常:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 10, Size: 1 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.get(ArrayList.java:322) at demo.RuntimeDemo.main(RuntimeDemo.java:10)
②非运行时异常,IoException为例:
public class IoDemo { public static void main(String[] args) { File f = new File(""); try { f.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }
这里要求我必须捕获或者抛出,看结果:
java.io.IOException: 系统找不到指定的路径。 at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:883) at demo.IoDemo.main(IoDemo.java:10)
(二)异常的两种处理方式:抛出和捕获。
抛出异常表示当前的错误不在本方法中处理,交由调用当前方法的地方处理;捕获异常表示当前错误在本方法中通过catch捕获进行一些特殊处理。
①首先来看try...catch:
public class ThrowDemo { public void cathcMethod(){ System.out.println("running cathcMethod..."); File file = new File(""); try { file.createNewFile(); } catch (IOException e) { //直接在本方法把异常消化掉 System.out.println("running cathcMethod's catch..."); } } public static void main(String[] args) { ThrowDemo td = new ThrowDemo(); td.cathcMethod(); System.out.println("running???????"); }
这里main函数里会运行cathcMethod方法,而该方法绝对会出现IOException异常,我们要看的是当运行完cathcMethod后,下面一句 System.out.println("running???????")是否会执行,看结果:
running cathcMethod... running cathcMethod's catch... running???????
结果是,虽然td.cathcMethod();发生了异常,但是没有影响后面的代码的执行。这是因为当程序运行到cathcMethod方法时会发生IOException,但是cathcMethod方法通过catch直接捕获了异常,等于这个错误被该方法消化了,外面是不知道里面情况的。
这种捕获异常的方法通常是不可取的,因为你莫名其妙把这个重要的一个异常“吃”掉了,很可能会影响到一个系统的正常运作,通常我们会考虑抛出异常。
抛出异常需要说到两个关键字:throw和throws,这个东西口头不好说,直接代码说话:
public class ThrowDemo { /** * * Function : 直接抛出异常 * @author : bless<505629625@qq.com> * @throws IOException */ public void throwsMethod() throws IOException{ System.out.println("running throwsMethod..."); File file = new File(""); file.createNewFile(); } public static void main(String[] args) throws IOException { ThrowDemo td = new ThrowDemo(); td.throwsMethod(); System.out.println("running??????"); } }
throws写在方法后面,表示当前方法可能会出现的异常,一但加上了throws xxxException则该异常在方法体内就不需要用try...catch刻意捕获了(当然你也可以写,后面再说)。这个throws表示什么意思呢?它表示当运行当前方法时,可能会出现一个异常,但是当前方法不做处理,让调用该方法的地方去处理。我们看到main方法也有throws IOException ,这样再往上抛的话就到java虚拟机了,java虚拟机捕获到错误时就会打印错误信息到控制台,我们看结果:
running throwsMethod... Exception in thread "main" java.io.IOException: 系统找不到指定的路径。 at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(File.java:883) at demo.ThrowDemo.throwsMethod(ThrowDemo.java:16) at demo.ThrowDemo.main(ThrowDemo.java:21)
我们看到上面运行了throwsMethod方法,但因为发生了异常终止了main方法里System.out.println("running??????");的执行,这是因为当运行到某个方法,该方法发生异常时候,如果该方法是throws了异常的,则该程序就只执行到发生异常的方法,然后把异常再往上处理。当然如果你在main函数里像厦门这样写,结果又不一样了:
public static void main(String[] args) { ThrowDemo td = new ThrowDemo(); try { td.throwsMethod(); } catch (IOException e) { System.out.println("running error..."); } System.out.println("running??????"); }
(三)回头说说我正在开发的组件,后台三层Dao层(数据库操作)、Service层(业务操作)、Action层(实现页面交互),代码运行顺序依次是dao->service->action,action采用的是struts2框架,我的设计思想是dao和service对异常进行封装,到action层通过拦截器截获异常进行处理。为了明确发生了什么异常,个人建议使用自定义异常,通过自定义异常来处理各种错误。
首先看自定义异常代码:
public class SystemException extends RuntimeException{ private static final long serialVersionUID = 1L; String errorCode = "default"; public SystemException(){ super(); } public SystemException(Throwable e){ super(e); } public SystemException(String message){ super(message); } public SystemException(String message,Throwable e){ super(message,e); } public SystemException(String errorCode,String message){ super(message); this.errorCode = errorCode; } /** * 最常用的构造方法 * @param errorCode 错误ID * @param message 错误消息 * @param e 异常信息 */ public SystemException(String errorCode,String message,Throwable e){ super(message,e); this.errorCode = errorCode; } public String getErrorCode() { return errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } }
首先介绍几点我这个自定义异常:
①为什么继承RuntimeException: 因为RuntimeException是运行时异常,是不需要被捕获或强行抛出的,如果自定义异常继承Exception,后面方法都得捕获或throws,很麻烦。
②errorCode的作用:错误编号,这个是关键,因为系统可能会有很多种异常,我们可以给每种异常定义一个错误编号,然后在action层通过拦截器捕获自定义异常的errorCode,就可以知道是什么错误了。
再说Dao层使用的是spring封装过的类,spring把所有非运行时异常全部转换成了运行时异常。为了保证用户能明白执行什么,我会对每个方法捕获RuntimeException然后转换成自定义异常:
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao { public Object getObject(Class clazz, Serializable id) throws RuntimeException { Object o = null; try { o = getHibernateTemplate().get(clazz, id); } catch (RuntimeException e) { throw new SystemException("query_error","Sql exceptioin : query data error!",e);; } return o; } }
其它层可能涉及到非运行时异常,比如action层ajax,后台可能会打印信息到页面,这时可能会有IOException:
PrintWriter out; try { out = response.getWriter(); } catch (IOException e) { throw new SystemException("io_error","response.getWriter() error!",e); }
未完待续...
评论
errorCode完全可以做成枚举
errorCode的作用是让开发人员立刻理解错误的大致方向,然后好迅速定位排
errorCode 其实有一个问题,就是增加了开发人员的工作量。需要开发人员一边写程序,旁边还要放一个错误映射表,当他要抛出异常的时候,来查表确定异常对应的errorCode值,而且如果没有查到对应的errorCode值,还需要自行添加?
errorCode用不用取决于开发人员自觉性,如果我throw new SystemException(e);就没有errorCode。但是如果每个开发人员都谨慎抛出异常,那么errorCode就能很好运作,这个的确是需要一定工作量,但是一旦你做好了就一劳永逸的事。
至于你说的自行添加,肯定是多个开发人员一起往里添内容啦
errorCode完全可以做成枚举
errorCode的作用是让开发人员立刻理解错误的大致方向,然后好迅速定位排
errorCode 其实有一个问题,就是增加了开发人员的工作量。需要开发人员一边写程序,旁边还要放一个错误映射表,当他要抛出异常的时候,来查表确定异常对应的errorCode值,而且如果没有查到对应的errorCode值,还需要自行添加?
errorCode完全可以做成枚举
errorCode的作用是让开发人员立刻理解错误的大致方向,然后好迅速定位排
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao { public Object getObject(Class clazz, Serializable id) throws RuntimeException { Object o = null; try { o = getHibernateTemplate().get(clazz, id); } catch (RuntimeException e) { throw new SystemException("query_error","Sql exceptioin : query data error!",e);; } return o; } }
为什么要申明抛出RumtimeException?
其次为什么在捕获RumtimeException再重新抛出你自定义的RumtimeException后还要让代码继续执行下去?,如果我在你所谓的action层上这样调用你的代码:
Object obj = dao.getObject(xxx.class,id);
我是不是还要:
if(null!=obj) //do something else
再者,为何要定义那些所谓的error_code,如果我维护你的代码,再得到异常后,我是不是要进去你的代码,看一下error_code的定义?异常的语义本身就很丰富,为什么还要定义什么error_code?
毋庸置疑,维护你所写的代码将会是艰辛的事。
①为什么要申明抛出RuntimeException?
因为spring在封装hibernate的时候已经将所有jdbc的非运行时异常(如SQLException)转换成自定义的运行时异常(RuntimeException),所以用RuntimeException捕获已经足够
②还要不要if(null!=obj)//do something else
答案是:不用,如果在上面发生了异常以后,异常会一直向上抛,直到某个地方在此try...catch捕获它,前面我已经说过:代码运行顺序依次是dao->service->action,action采用的是struts2框架,如果dao层抛出了RuntimeException,到action层通过拦截器截获异常进行处理即可
③为什么要定义error_code?
正是为了代码维护,这个error_code是为了给用户看的,我把所有的error_code按照编辑依次写到一个文件中,当发生异常的时候,拦截器获取error_code编号再去文件中找对应的错误信息,然后把文件中已经写好的错误信息返回给用户。比如在文件中定义一个编号为error_code001,错误消息为:该条数据已被删除。最后用户在页面上就能看到的信息是:该条数据已被删除。
异常的语义确实太丰富了,所以我们程序员要尽量去分析不同情况的异常,最后转换成用户能看懂的错误消息(总不能让用户看到:java.lang.NullPointerException
这样的信息吧)
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao { public Object getObject(Class clazz, Serializable id) throws RuntimeException { Object o = null; try { o = getHibernateTemplate().get(clazz, id); } catch (RuntimeException e) { throw new SystemException("query_error","Sql exceptioin : query data error!",e);; } return o; } }
为什么要申明抛出RumtimeException?
其次为什么在捕获RumtimeException再重新抛出你自定义的RumtimeException后还要让代码继续执行下去?,如果我在你所谓的action层上这样调用你的代码:
Object obj = dao.getObject(xxx.class,id);
我是不是还要:
if(null!=obj) //do something else
再者,为何要定义那些所谓的error_code,如果我维护你的代码,再得到异常后,我是不是要进去你的代码,看一下error_code的定义?异常的语义本身就很丰富,为什么还要定义什么error_code?
毋庸置疑,维护你所写的代码将会是艰辛的事。
发表评论
-
关于HQL和JDBC SQL中字段相除的一点小经验
2016-02-25 11:42 3364最近在做一个功能,产 ... -
Java异常那些不得不说的事
2014-11-29 12:09 17099一、在finally块中做数据回收操作 比如数据库连接都 ... -
基于Java的通用图表接口设计与实现
2014-02-26 18:00 15122现如今,互联网上充斥 ... -
JSONObject转换JSON--将Date转换为指定格式
2014-02-18 22:12 77174项目中,经常会用JSONObject插件将JavaBean或 ... -
Java开发笔记
2012-12-13 10:30 18101、Map<key,value>的remove ... -
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: on near line 1解决方案
2012-09-12 16:03 28132文章摘自:http://blog.csdn.net/yangw ... -
Java反射常用机制
2012-08-04 17:58 8398首先要求大家对Java泛型知识有所了解,因为程序代码中大量使 ... -
JDBC常用API之外的总结
2012-04-20 15:43 6485做JAVA的人玩JDBC肯定已经很熟练了,像DriverMa ... -
JSP实现指定盘符路径下的图片显示
2012-02-14 09:54 23599开发人员都知道<img src="" ... -
Java实现文件上传
2012-02-13 23:57 319791最近自己在做一个小系统玩的时候涉及到了文件的上传,于是在网上 ... -
commons-fileupload实现文件上传功能实例
2012-01-17 21:50 67433Apache提供的commons-fileupload ja ... -
汉字转拼音pinyin4j
2011-09-03 09:57 2174以前在项目中遇到汉字转拼音的情况,于是在网上找到了pinyi ... -
J2EE监听器和过滤器基础
2011-09-02 16:56 7346Servlet程序由Servlet,Filter和Liste ... -
java通信之Socket通信基础
2011-06-21 21:08 5994正处于网络环境下的两个程序,它们之间通过一个交互的连接来实现数 ... -
Java通信之URL通信基础
2011-06-21 11:15 3476java对网络通信以及提供了比较全面的jdk支持,java.n ... -
java集合排序笔记
2011-06-15 15:21 1633public class CollectionDemo imp ... -
Java IO笔记
2011-06-15 14:23 1077public static void main(String ... -
java web项目整体异常处理机制
2011-06-08 22:04 13081在实际的j2ee项目中,系 ... -
解决带换行符的字段在web页面无法换行的问题
2011-05-31 11:46 18958在BS项目,有时候大家 ... -
[Microsoft][ODBC Microsoft Access 驱动程序] INSERT INTO 语句的语法错误的可能原因
2011-05-30 23:34 6160今天使用JDBC-ODBC桥接来操作Access数据库,发现了 ...
相关推荐
3. **异常处理**:理解Java的异常处理机制,如何使用try-catch-finally语句块进行错误捕获和处理,以及自定义异常。 中级阶段: 4. **IO流与NIO**:讲解Java的输入输出流体系,包括文件操作、网络通信等,以及新...
在Java学习的初级阶段,经常会遇到一系列挑战,这些问题涵盖了基础语法、面向对象编程、异常处理、集合框架等关键领域。以下是一些常见的Java初级学习问题及其详细解释: 1. **基础语法** - 变量声明:理解变量的...
Java初级程序员试题主要涵盖Java语言的基础知识,包括但不限于语法、数据类型、控制结构、类与对象、异常处理、集合框架等方面。以下是对这些知识点的详细解释: 1. **Java语法**:Java是一种强类型、面向对象的...
七、异常处理 在游戏开发中,错误和异常是难以避免的。良好的错误处理机制可以提高游戏的稳定性和用户体验。例如,当用户尝试执行非法操作时,应给出友好的提示信息。 八、持续优化 项目鼓励大家发现并修复bug,这...
Java中的异常类是一种用于处理错误和异常的机制。异常类可以用于catch和throw异常,以便更好地处理程序中的错误。 九、基础命名规范 Java中的命名规范非常重要,命名规范可以提高代码的可读性和维护性。Java中的...
通过try-catch语句捕获并处理可能出现的异常,比如资源找不到、网络问题等。 10. **设计模式**:在实现游戏逻辑时,设计模式如单例模式(用于游戏主循环)、工厂模式(用于创建游戏对象)和观察者模式(用于事件...
6. **异常处理**:掌握try-catch-finally语句块,理解检查型异常和运行时异常的区别,以及如何自定义异常。 7. **集合框架**:学习ArrayList、LinkedList、HashSet、HashMap等集合类的使用,以及迭代器的概念和应用...
3. **异常处理**:在Java中,异常处理是一个重要的特性,它允许程序员通过try-catch-finally块来捕获和处理程序运行时可能出现的错误。源码中可能会有对异常处理的实例,帮助学习者理解何时何地应使用异常处理。 4....
异常处理是Java中的错误处理机制,可以帮助我们优雅地处理程序运行时可能出现的问题。集合框架提供了存储和操作对象的高效数据结构,而IO流则用于读写文件和其他输入输出源。 晋升到高级阶段,Java并发编程是必不可...
Java作为一门广泛使用的编程语言,其初级面试题涵盖了基础语法、面向对象特性、集合框架、异常处理、IO流、多线程、网络编程等多个方面。以下是对这些知识点的详细阐述: 1. **基础语法**:Java的基础语法包括变量...
3. **异常处理**:Java强调异常处理,案例可能展示了如何使用try-catch-finally块来捕获和处理错误。 4. **IO流**:学习Java的初学者会接触到输入输出流,用于读写文件或网络通信。 5. **集合框架**:如ArrayList...
5. **异常处理**:Java强调异常处理,通过try-catch-finally语句块捕获和处理可能出现的错误。在案例中,可能会遇到如何适当地处理可能出现的异常情况,以保证程序的健壮性。 6. **函数与方法**:函数是程序的基本...
5. **异常处理**:Java中的异常处理是通过try-catch-finally语句块实现的,用于捕获并处理程序运行时可能出现的错误。理解何时抛出异常以及如何妥善处理异常,可以提高程序的健壮性。 6. **IO流**:输入/输出流(IO...
7. **异常处理**:在编写程序时,合理的异常处理能提高代码的健壮性。在飞机大战项目中,可能会遇到如文件不存在、编码问题等异常,学习者可以学习如何使用try-catch语句来处理这些问题。 8. **编码格式GBK**:该...
2. **异常处理**: - 在开户过程中可能出现各种异常情况,如输入非法、账户已存在等,需要使用try-catch语句进行异常捕获和处理。 3. **集合框架**: - 用户和账户信息通常需要存储在数据结构中,如ArrayList或...
3. **异常处理**:try-catch-finally语句块,自定义异常。 4. **数组和集合**:数组的使用,ArrayList、LinkedList、HashSet、HashMap等集合类的理解与应用。 5. **方法和函数**:参数传递,重载和重写。 6. **字符...
此外,异常处理是确保程序健壮性的重要部分。Java强制使用try-catch-finally结构来捕获和处理异常,第一章的示例可能涵盖了如何正确地处理和抛出异常。 最后,Java标准库(Java API)提供了大量预定义的类和方法,...
- 异常处理:掌握try-catch-finally块,处理程序中的异常情况。 - 输入/输出流:熟悉文件读写操作。 **4. Web开发基础** 作为一名Java程序员,掌握Web开发技术是必不可少的。这包括: - HTML/CSS/JavaScript:...
2. **Java异常处理**: - **异常分类**:Java中的异常分为检查异常(Checked Exception)和运行时异常(Unchecked Exception)。 - **异常的抛出与捕获**:理解try-catch-finally语句块,知道如何使用throw关键字...
9. **异常处理**:最后的第9章可能涉及到Java的异常处理机制,包括try-catch-finally语句块,以及预定义的异常类。 这些测试题涵盖了Java编程的基本元素,通过解答这些问题,学习者可以检验自己的理解程度,加深对...