`
sw1982
  • 浏览: 511450 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

异常处理的哲学Tips for Using Exceptions(1)

阅读更多

原文摘自Core Java Volume I 7th Edithon中的章节。


最近写代码碰到了很多异常处理的问题。包括在DAO层处理什么异常,抛出什么异常到Service层。 自己实现的基础方法是内部消化异常还是抛出一些异常呢?找出了core java翻了一下,顺便翻译出来做个笔记。



一。Exception handling is not supposed to replace a simple test.

异常处理机制不应该取代正常的判断逻辑。 下面第2段代码示例了一个使用异常取代非空判断的错误用法

As an example of this, we wrote some code that uses the built-in Stack class. The code in Example 11-3 tries 1,000,000 times to pop an empty stack. It first does this by finding out whether the stack is empty.

if (!s.empty()) s.pop();


Next, we tell it to pop the stack no matter what. Then, we catch the EmptyStackException that tells us that we should not have done that.

try()
{
   s.pop();
}
catch (EmptyStackException e)
{
}   

 

这一点还是比较容易做到的,没有什么可说


二。Do not micromanage exceptions.

Many programmers wrap every statement in a separate TRy block.

不要在做同一件事情的方法内,过细的划分异常处理,使得每个异常的处理代码各自为阵。

badstyle:

OutputStream out;
Stack s;

for (i = 0; i < 100; i++)
{
   try
   {
      n = s.pop();
   }
   catch (EmptyStackException s)
   {
      // stack was empty
   }
   try
   {
      out.writeInt(n);
   }
   catch (IOException e)
   {
      // problem writing to file
   }
}



 goodstyle:

try
{
   for (i = 0; i < 100; i++)
   {
      n = s.pop();
      out.writeInt(n);
   }
}
catch (IOException e)
{
   // problem writing to file
}
catch (EmptyStackException s)
{
   // stack was empty
}



 理由:Think about the task that you want the code to accomplish. Here we want to pop 100 numbers off a stack and save them to a file. (Never mind why—it is just a toy example.) There is nothing we can do if a problem rears its ugly head. If the stack is empty, it will not become occupied. If the file contains an error, the error will not magically go away. It therefore makes sense to wrap the entire task in a try block. If any one operation fails, you can then abandon the task.

上面的示例展示从栈内拿出100个数字写到文件。一旦出现栈空异常或者IO写异常我们无能为力。反而是将整个过程集中到try模块,一旦捕捉到了任何操作失败抛出的异常,我们可以从全局上取消整个任务。


“一个方法只做一件事情”是另外一个面向对象的原则,如果发现一个方法里面需要分别对不同步骤进行异常的处理,而分开的异常模块会干扰到整个方法的“完整性”(类似破坏了数据库的事务一致性),这个时候可能就需要考虑重构方法了


三。Make good use of the exception hierarchy.

最大程度上使用异常体系的继承体系,精确定位异常。

!!Don't just throw a RuntimeException . Find an appropriate subclass or create your own.

!!Don't just catch Throwable . It makes your code hard to read and maintain.

不要仅仅抛出RuntimeException、Throwable等无助于事的异常。

!!don't throw them for logic errors。Callers often need to catch exceptions that they know can never happen

不要给逻辑错误抛出异常

!!Do not hesitate to turn an exception into another exception that is more appropriate.

For example, when you parse an integer in a file, catch the NumberFormatException and turn it into a subclass of IOException or MySubsystemException .

在找到更适合的异常时,千万不要犹豫~~转换异常。 比如在一个File文件操作中进行整数的转换,一个数字格式错误异常的意义远远不如给出 IOException 或者自定义的异常信息明确。


很多人领悟了异常处理的其他精髓要点,在适当的地点,丢出了“系统适当”的异常。比如上面例子,数字转换出错抛 NumberFormatException理论上是完全合适并且正确的。但是 NumberFormatException能让你联想到是在File文件操作函数里面抛出来的么?个人觉得这里输出一个MyFileWriteException更能让人定位错误,配合log日志

log.error(" MyFileWriteException---write File got NumberFormatException ");



四。Do not squelch exceptions.

不要贪图掩盖的异常

badstyle:

public Image loadImage(String s)
{
   TRy
   {
      code that threatens to throw checked exceptions
   }
   catch (Exception e)
   {} // so there
}


Now your code will compile without a hitch. It will run fine, except when an exception occurs. Then, the exception will be silently ignored. If you believe that exceptions are at all important, you should make some effort to handle them right.

虽然你可以得到正常的编译,并且异常也不会抛出。但是要注意到,如果是一些重要的异常,还是需要做出努力去正确的处理它们。


掩盖异常是对别人的犯罪。。。当调用一个只返回ture or flase,却不抛出任何异常的I/O函数,总会让我心里发慌。。即便定位到这个函数出错,也无法根据异常去调试


五。When you detect an error, "tough love" works better than indulgence.

发现异常,严格的处理比适当的放任更好。

Some programmers worry about throwing exceptions when they detect errors. Maybe it would be better to return a dummy value rather than throw an exception when a method is called with invalid parameters. For example, should Stack.pop return null rather than throw an exception when a stack is empty? We think it is better to throw a EmptyStackException at the point of failure than to have a NullPointerException occur at later time.

许多程序员担心抛出异常信息。也许对调用一个参数无效的函数,返回一个伪值要比抛出异常更好(e.g -1ll表示调用错误)。但是对于Stack.pop 返回null而言,抛出EmptyStackException 要比未来碰到NullPointerException 要显得更好。


”返回null总是不对的:)“Effective Java中就有这么一条。对于某些可以向外隐匿的错误通过返回-1等特殊值在一定程度上可行。返回null确实是罪过。


六。Propagating exceptions is not a sign of shame.

将异常上升到更高层次去处理,并不是一个令人害羞的事情。

Many programmers feel compelled to catch all exceptions that are thrown. If they call a method that throws an exception, such as the FileInputStream constructor or the readLine method, they instinctively catch the exception that may be generated. Often, it is actually better to propagate the exception instead of catching it:

public void readStuff(String filename) throws IOException // not a sign of shame!
{
   InputStream in = new FileInputStream(filename);
   . . .
}


 Higher-level methods are often better equipped to inform the user of errors or to abandon unsuccessful commands.

更高级别的方法通常会有更多使用错误的信息或者中断掉不成功的调用。



分享到:
评论

相关推荐

    异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt异常处理.ppt

    - **捕获异常(Catching Exceptions)**:使用`try-catch`语句块来捕获并处理异常。`try`块包含可能会抛出异常的代码,而`catch`块则定义了如何处理特定类型的异常。 4. **异常类的层次**:Java中的异常类都继承自...

    使用企业库进行异常处理

    2. **策略定义与维护**:异常处理策略可以在高层定义,由系统管理员或开发人员决定如何处理异常,通过配置而非代码进行修改。 3. **内置异常处理功能**:包括记录异常信息、替换异常以隐藏敏感信息、包装异常以添加...

    java 异常处理ppt

    异常处理主要涉及两个关键部分:捕获异常(catching exceptions)和声明抛弃异常(throwing exceptions)。在Java中,异常处理通常使用`try-catch`块来实现。`try`块包含可能会抛出异常的代码,而`catch`块则包含...

    Struts1异常处理

    5. **结合Log4j等日志框架**:在处理异常时,通常会配合Log4j等日志框架记录异常信息,以便于调试和问题追踪。 6. **错误页面设计**:为了提供良好的用户体验,错误页面应当清晰地向用户展示错误信息,同时避免暴露...

    Laravel开发-exceptions 错误异常处理工具,支持开发和生产环境,使用 Whoops 进行错误显示

    Laravel通过`throw new Exception`抛出异常,使用`try...catch`结构捕获并处理异常。 - Laravel提供了一个自定义的异常处理类`App\Exceptions\Handler`,它是所有应用异常的中央调度点。在这个类中,你可以定义如何...

    Java异常处理体系

    1. **try**:try块是异常处理的起点,它包含可能会抛出异常的代码。如果在try块内部发生了异常,控制权将立即转移到相应的catch块。 2. **catch**:catch块用于捕获try块中抛出的异常。一个try块可以跟随多个catch...

    Struts2异常处理机制

    当Struts2与Spring集成时,可以在Spring的配置文件中定义AOP切面来处理异常,这可以进一步增强异常管理的灵活性。 通过以上这些方式,Struts2的异常处理机制为开发者提供了丰富的选项,能够确保程序在遇到异常时能...

    实验六:Java异常处理

    一旦异常被抛出,程序的正常执行流程被打断,然后寻找适当的异常处理器来处理异常。 2. **异常的分类**: Java异常分为两大类:检查性异常(Checked Exceptions)和运行时异常(Unchecked Exceptions)。检查性...

    高效java异常处理机制

    在处理异常时,应该记录详细的异常信息,包括堆栈跟踪,这对于定位和解决问题至关重要。 11. **避免在finally块中抛出异常** finally块中的代码不应抛出新的异常,因为它会覆盖原有的异常信息,使调试困难。 12....

    java试验报告之异常处理程序设计

    在Java中,`try-catch`块用于捕获和处理异常。在`try`块内,可能抛出异常的代码会被执行。如果发生异常,控制流会立即跳转到与该异常匹配的`catch`块。每个`catch`块可以捕获一种特定类型的异常,或者通过使用父类...

    Laravel开发-exceptions

    1. **异常处理基础** - 在PHP中,异常是通过`throw new Exception`语句抛出的,用于中断代码执行并传递错误信息。 - Laravel扩展了这个概念,提供了一个统一的异常处理接口,方便开发者管理和捕获各种异常。 2. *...

    java 异常处理 代码实例

    为了更好地处理异常,Java还提供了一些内置的异常类,如`IllegalArgumentException`、`NullPointerException`、`ArrayIndexOutOfBoundsException`等,它们对应于常见的编程错误。此外,开发者也可以自定义异常类,...

    Using Cortex-M3/M4/M7 Fault Exceptions

    本文主要围绕“Using Cortex-M3/M4/M7 Fault Exceptions”这一主题,深入探讨了Cortex-M处理器在遇到非法内存访问和错误程序条件时的异常处理流程,这对于理解和优化软件开发过程至关重要。 首先,Cortex-M处理器...

    java异常处理

    - 捕获(Catching):当异常发生时,程序会尝试通过`try-catch`块来捕获并处理异常。 - 抛出(Throwing):当遇到无法正常处理的情况时,可以使用`throw`关键字抛出一个异常。 - 异常处理链(Exception Chaining...

    struts1.x 异常处理机制

    另外,你还可以通过继承`org.apache.struts.action.ExceptionHandler`接口来自定义异常处理器,这允许你在整个应用程序范围内统一处理异常,而不仅仅是单个Action。 此外,对于Struts1.x中与Action相关的异常,如`...

    Python库 | py_exceptions-1.1.0-py3-none-any.whl

    1. **自定义异常类**:`py_exceptions`库定义了一系列预定义的异常类,这些类继承自Python内置的`Exception`类及其子类。这些类通常对应于特定的错误场景,比如`NetworkError`、`AuthenticationError`等,使得异常...

    C_与C++中的异常处理.pdf

    程序员需要了解如何在这些情况下适当地处理异常,以避免程序崩溃或资源泄露等问题。 #### 六、Microsoft对于的实现版本中的异常处理 ##### 6.1 Microsoft的实现 Microsoft的C++编译器提供了对`&lt;new&gt;`头文件的特殊...

    java程序中的异常处理

    - `try-catch`块用于捕获并处理异常。如果`try`块内的代码抛出了异常,则`catch`块将捕获该异常,并执行相应的处理逻辑。 4. **异常处理中的finally块**: - 虽然本例中没有体现,但在实际开发中经常使用`...

Global site tag (gtag.js) - Google Analytics