异常传播指南(Java) [英] Guidelines on Exception propagation (in Java)

查看:99
本文介绍了异常传播指南(Java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有关于Java中异常传播的指导原则?



什么时候在方法签名中添加异常?
例如:如果一个重要的程序资源丢失时抛出异常,并且只能在顶层处理,那么我是否会通过使用这种错误方法的所有方法通过所有方法传播所有方法?



有没有什么好的做法?任何不好的做法?



如果我很模糊,我很抱歉,但我只是在寻求有关例外的编程风格的一般(一般)建议。 p>

解决方案

过去帮助我的指南包括:




  • 当方法无法处理异常时抛出异常,更重要的是应该由调用者处理。一个很好的例子就是Servlet API中的doGet()和doPost()抛出ServletException或IOException异常,在某些情况下无法正确读取该请求。这些方法都不能处理异常,但是容器是(在大多数情况下,这导致了50x错误页面)。

  • 如果方法无法处理。这是上述的推论,但适用于必须捕获异常的方法。如果捕获到的异常无法通过该方法正确处理,那么最好是将其发泡。

  • 立即抛出异常。这可能听起来模糊,但是如果遇到异常情况,那么抛出一个指示原始故障点的异常,而不是尝试通过错误代码来处理故障是一个很好的做法,直到被认为适合于抛出异常。换句话说,尝试将混合异常处理与错误处理最小化。

  • 记录异常或将其发泡,但不要同时执行。记录异常通常表示异常堆栈已经完全展开,表明没有发生异常的进一步冒泡。因此,不建议同时进行这两个操作,因为它经常会导致调试中的令人沮丧的体验。

  • 使用 java.lang.Exception (检查异常),当您除了来电者处理例外。如果调用者没有处理异常,这将导致编译器抛出错误消息。请注意,这通常会导致开发人员在代码中吞咽异常。

  • 使用 java.lang.RuntimeException (未经检查的异常)来发出编程错误。这里推荐的异常类包括 IllegalStateException IllegalArgumentException UnsupportedOperationException 等。同样,必须注意使用异常类,如NullPointerException (几乎总是一个不好的做法扔一个)。

  • 使用异常类层次结构来传递有关各层异常的信息。通过实现层次结构,您可以推广调用者中的异常处理行为。例如,您可以使用像DomainException这样的根异常,它具有多个子类,如InvalidCustomerException,InvalidProductException等。这里的注意事项是,如果将每个单独的异常情况表示为单独的异常,则异常层次结构可能会非常快地爆炸。

  • 避免捕获您无法处理的异常。很明显,但很多开发人员尝试捕获java.lang.Exception或java.lang.Throwable。由于可以捕获所有子类异常,因此当捕获全局异常类时,应用程序的运行时行为通常会模糊。毕竟,一个人不想捕捉OutOfMemoryError - 应该如何处理这样的异常?

  • 谨慎地包装例外。重新启动异常将重置异常堆栈。除非原始原因已经提供给新的异常对象,否则它将永远丢失。为了保存异常堆栈,必须将新的异常对象提供给新的异常构造函数。

  • 只有当需要时才将检查的异常转换为未选中的异常 。当包装异常时,可以包装一个被检查的异常并抛出一个未被检查的异常。这在某些情况下是有用的,特别是当意图中止正在执行的线程时。然而,在其他情况下,这可能会导致一些痛苦,因为编译器检查不执行。因此,将被检查的例外修改为未选中的例外并不意味着盲目地完成。


Are there any guidelines on exception propagation in Java?

When do you add an exception to the method signature? For example: if an exception is only thrown when an essential program resource is missing, and can only be handled at the top level, do I propagate it through all methods using this exception through all the methods using the erring method?

Are there any good practices? Any bad practices?

I'm sorry if I'm being vague, but I'm just looking for some (general) advice on programming style concerning exceptions.

解决方案

Guidelines that have helped me in the past include:

  • Throw exceptions when the method cannot handle the exception, and more importantly, should be handled by the caller. A good example of this happens to present in the Servlet API - doGet() and doPost() throw ServletException or IOException in certain circumstances where the request could not be read correctly. Neither of these methods are in a position to handle the exception, but the container is (which results in the 50x error page in most cases).
  • Bubble the exception if the method cannot handle it. This is a corollary of the above, but applicable to methods that must catch the exception. If the caught exception cannot be handled correctly by the method, then it is preferable to bubble it.
  • Throw the exception right away. This might sound vague, but if an exception scenario is encountered, then it is a good practice to throw an exception indicating the original point of failure, instead of attempting to handle the failure via error codes, until a point deemed suitable for throwing the exception. In other words, attempt to minimize mixing exception handling with error handling.
  • Either log the exception or bubble it, but don't do both. Logging an exception often indicates that the exception stack has been completely unwound, indicating that no further bubbling of the exception has occurred. Hence, it is not recommended to do both at the same time, as it often leads to a frustrating experience in debugging.
  • Use subclasses of java.lang.Exception (checked exceptions), when you except the caller to handle the exception. This results in the compiler throwing an error message if the caller does not handle the exception. Beware though, this usually results in developers "swallowing" exceptions in code.
  • Use subclasses of java.lang.RuntimeException (unchecked exceptions) to signal programming errors. The exception classes that are recommended here include IllegalStateException, IllegalArgumentException, UnsupportedOperationException etc. Again, one must be careful about using exception classes like NullPointerException (almost always a bad practice to throw one).
  • Use exception class hierarchies for communicating information about exceptions across various tiers. By implementing a hierarchy, you could generalize the exception handling behavior in the caller. For example, you could use a root exception like DomainException which has several subclasses like InvalidCustomerException, InvalidProductException etc. The caveat here is that your exception hierarchy can explode very quickly if you represent each separate exceptional scenario as a separate exception.
  • Avoid catching exceptions you cannot handle. Pretty obvious, but a lot of developers attempt to catch java.lang.Exception or java.lang.Throwable. Since all subclassed exceptions can be caught, the runtime behavior of the application can often be vague when "global" exception classes are caught. After all, one wouldn't want to catch OutOfMemoryError - how should one handle such an exception?
  • Wrap exceptions with care. Rethrowing an exception resets the exception stack. Unless the original cause has been provided to the new exception object, it is lost forever. In order to preserve the exception stack, one will have to provide the original exception object to the new exception's constructor.
  • Convert checked exceptions into unchecked ones only when required. When wrapping an exception, it is possible to wrap a checked exception and throw an unchecked one. This is useful in certain cases, especially when the intention is to abort the currently executing thread. However, in other scenarios this can cause a bit of pain, for the compiler checks are not performed. Therefore, adapting a checked exception as an unchecked one is not meant to be done blindly.

这篇关于异常传播指南(Java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆