Java是少数几个把exception放在语言层来处理的语言之一,也曾作为一个重要卖点来吹捧,但是我们真地在正确的使用exception吗?我们从exception机制中得到好处了吗?我看未必!
我们现在都知道捕获而不处理的是有害处的,但是简单的e.printStackTrace()甚至System.out.println(e)或者log.error(e, "Error Occurs!")这样就算处理了吗?他对我们应用程序的健壮性或者程序处理有何好处?答案是绝对没有,他只为你在发生问题后来查找错误原因提供些帮助,用户并没有得到任何的好处!自从java1.4后引入了exception层次(cause)后,于是大家多了一种自认为更好的选择throw new UniqueBizzException(anyException);多么优雅,我的程序都是抛出我的意外!但事实真是这样吗?
在我看来这是一个更糟糕的用法。想想看,如果你是这个方法的使用者,不管什么错误,你统统都是得到一个UniqueBizzException,你能对他做些什么呢?好像也只能再一次抛出去。
我们还是回过头来看看为什么我们需要exception,我的观点是exception就是
对错误进行类型化,对象化。就如同其他事物被类型化,对象化一样!它让错误有了更多的信息、更多内涵。从而我们在程序中可以处理它而不是把它直接抛给可怜的用户甚至干脆屏蔽掉!根据这些错误类型或者信息,从而可以改变我们的程序处理流程,对不同的错误采取不同处理方式,这才是exception的正确用途。例如发生ValidateException时候,我们应该收集发生错误的field和原因,重新回到form去显示提示用户,发生UserAccountExpiredException则要求用户重新登陆等等。当然并不一定都要使用类型,例如像SQLException那样包含errorCode来区分错误类型也可以。总之当你需要抛出Exception的时候,你的exception中应该包含可以让
程序简易获取错误类型和原因的信息,从而决定处理方式,而不是一个笼统的错误让接下来的使用者无法处理。
当然再好的程序也不可能处理全部错误,这时候怎么办呢?既然不能处理,那就不管它,让它一层层交接给可以处理他的调用者!java提供了另一种错误类型:unchecked exception(RuntimeException以及其子类)。java语言不会强行要求使用者处理或者抛出这类错误,发生的时候它会自动抛出。最经典的反模式是EJB中的RemoteException,如果你捕获了这个错误,你能做什么呢?什么也不能做,只要在最后告诉用户这是一个系统错误,它可能的原因1、程序错误2、某种原因服务暂时不能用等等。总之这个是应用程序无法处理的。
既然你什么都不能做,那就应该什么也不要做,就应该是一个unchecked exception。而不应该一次次抓了又放,或者包一层再放。这样做除了让程序更罗嗦、错误藏得更深、内存占用更多,没有任何好处!也许有人会叫,可能涉及到一些资源释放的问题,所以要先抓后放。这就更加错了,资源释放要处理的话也应该放在finally块中,否则单是java中到处充斥的NPE早就把你资源耗光了。
以上是我在看pafa3种对exception处理的时候一些自己的思考,没有去查ThinkInJava或者EffectiveJava之类书中对Exception的建议,仅供大家探讨!
BTW:最近看到一个绝佳Idea,来自澳洲的Mike Cannon-Brookes(俺比较崇拜的实干家之一),留作记录:可以实现一个ThreadLocalLoggingAppender(Appender是log4j中的概念,pafa logging中应该有类似概念),利用Filter或者Interceptor在服务(可以是Servlet也可以是EJB)开始后启动,退出后关闭,如果发生exception就可以记录拥有全部信息,否则按设置记录信息!
public class ThreadLocalErrorLogAppender extends AppenderSkeleton {
protected void append(LoggingEvent event); {
ThreadLocalErrorCollection.add(System.currentTimeMillis();, event);;
}
public void close(); { }
public boolean requiresLayout(); {
return false;
}
}
分享到:
相关推荐
Java异常处理并不是一个简单的事情,不仅初学者很难理解,甚至一些有经验的开发者也需要花费很多时间来思考如何处理异常。阿里巴巴Java开发规范中有15条关于异常处理的说明,但是这些说明告诉了我们应该怎么做,却...
#### 三、思考题解答 1. **什么是异常?解释抛出、捕获的含义。** - **异常**是指程序运行过程中发生的非预期事件,这些事件可能会导致程序无法正常执行。Java中的异常分为两大类:**运行时异常**(如`...
异常处理(exception handling)则是保证程序健壮性的重要机制,通过try-catch块可以捕获并处理运行时可能出现的错误。 深入理解C++的内存管理,包括栈(stack)、堆(heap)和静态存储区(static storage),以及...
在PL/SQL中,可以通过EXCEPTION块来定义异常处理逻辑,例如,使用DBMS_OUTPUT.PUT_LINE()函数来输出错误信息。 ### 函数与触发器 函数(FUNCTION)是PL/SQL中用于执行特定计算并返回结果的一种编程结构。创建或...
直到开始学习java的时候,发现好多时候编写代码必须加上try…catch 模块,然而我每次都不深入理解,仅仅使用eclipse自动补全功能加上try…catch模块,或者直接在类上加入throws Exception最省事,完全不用思考。...
多思考业务的完整性,让你的代码更简炼,易写、易读、易于维护; 经过多个版本迭代,已经逐步走向稳定 二、FEILONG-CORE介绍 1. 简介: 让你从大量重复的底层代码中脱身,提高工作效率; 让你的代码更简炼,易写、...
通过实现`ActivityLifecycleCallbacks`,可以在每个Activity的生命周期方法中处理逻辑,包括获取当前Activity。这种方法的好处是不需要依赖反射,也不要求所有Activity都继承自特定基类,而是通过系统提供的API来...
本文主要总结了 Web 开发中的一些重要概念和技术点,包括对象序列化、值传递与引用传递、接口与抽象类、继承、方法重载、面向对象编程、集合框架、异常处理、多线程、异常框架、HashMap 与 Hashtable 的区别、 ...
12. Python 定义异常:使用 `class` 关键字创建一个新的异常类,通常是继承自内置的 `Exception` 类或其子类。 13. Python 抛出异常:使用 `raise` 语句,后面跟异常对象,如 `raise ValueError('错误信息')`。 14...
Exception是可捕获和处理的异常,是程序运行时可能出现的问题。 7. **final类**:声明为`final`的类不能被继承,确保其封闭性。 8. **堆与栈的区别**:栈用于存储基本类型和对象引用,遵循LIFO(后进先出)原则。堆...
- 可能会有处理异常的练习,利用exception对象捕获和处理错误。 通过这些课后练习,学习者能够亲手实践,加深对JSP核心概念的理解,提高实际开发能力。同时,这种练习方式也鼓励学生独立思考,解决问题,是理论学习...
通过理解Exception类、try-catch-finally结构,学习者可以编写出健壮的代码,处理运行时可能出现的问题。掌握异常处理机制,不仅能让程序运行更稳定,也是提高编程素质的重要标志。 总之,Java学习是一个系统的过程...
Java中的异常处理(Exception Handling)是什么,它的重要性是什么? 这些问题包括Java编程语言中最重要的方面,涵盖了Java的语言定义、面向对象编程和设计。它们可以帮助面试官了解您对Java编程语言的技能和知识,...
public static void main(String[] args) throws Exception { try (Rhodiola rhodiola = Rhodiola.start()) { //因为已经加上了@ActorGroup 注解,这句话不加也是可以的 rhodiola.register(Test.class).addGlob
实验 4 包、接口与异常处理(exception) 29 一、实验目的 29 二、实验要求 29 三、实验内容 29 (一)了解并使用 Java 的系统包 29 (二)创建并使用自定义包 29 (三)使用接口技术 31 (四)了解...
3. **异常处理**:在执行除法运算时,如果除数为零,程序需要捕获并处理`ArithmeticException`。此外,输入验证也是必不可少的,以防止无效的数值输入。 4. **控制结构**:根据描述中的“实验报告”,可能还涉及到...
3. **错误处理**:增加异常处理逻辑,确保程序在遇到意外情况时能够优雅地处理,而不是崩溃。 4. **国际化支持**:对于面向不同语言用户的软件,应考虑提供多语言支持。 5. **性能优化**:如果数据量较大,可以考虑...
6. **异常处理**:在处理除法时,需要考虑除以零的情况,这会抛出`ArithmeticException`。通过try-catch块,可以捕获并处理这种异常。 ```java try { result = num1 / num2; } catch (ArithmeticException e) { ...