Some suggestions on exception handling in effective Java

Half a month^ 2020-11-08 16:58:55
suggestions exception handling effective java

The first 1 strip : Use exceptions only for abnormal situations
The first 2 strip : Use checked exceptions for recoverable conditions , Use runtime exceptions for program errors
The first 3 strip : Avoid unnecessary use of checked anomalies
The first 4 strip : Try to use standard exceptions
The first 5 strip : The exception thrown should be appropriate for the corresponding abstraction
The first 6 strip : Every exception thrown by a method must be documented
The first 7 strip : Include failure in detail message -- Capture the message
The first 8 strip : Try to keep failure atomic
The first 9 strip : Don't ignore exceptions

The first 1 strip : Use exceptions only for abnormal situations
Suggest : Exceptions should only be used for abnormal conditions , They should never be used for normal control flow .
By comparing the following two codes .
Code 1
try {
int i=0;
while (true) {
} catch (IndexOutOfBoundsException e) {

Code 2
for (int i=0; i<arr.length; i++) {

The function of both codes is to traverse arr Array , And set the value of each element in the array to 0. Code 1 It's to terminate through an exception , It seems very difficult to understand , Code 2 Is terminated by array bounds . We should avoid code 1 This way, , There are three main reasons :
• The exception mechanism was designed to be used in abnormal situations , So it's rare that JVM Implementation attempts to optimize their performance . therefore , establish 、 The overhead of throwing and catching exceptions is expensive .
• Put the code in try-catch The return in the middle prevents JVM Implement some specific optimizations that might have been performed .
• The standard pattern of traversing arrays does not lead to redundant checks , Some modern JVM The implementation optimizes them .

actually , Exception based patterns are much slower than standard patterns . The test code is as follows :

public class Advice1 {

private static int[] arr = new int[]{1,2,3,4,5};
private static int SIZE = 10000;
public static void main(String[] args) {
long s1 = System.currentTimeMillis();
for (int i=0; i<SIZE; i++)
long e1 = System.currentTimeMillis();
System.out.println("endByRange time:"+(e1-s1)+"ms" );
long s2 = System.currentTimeMillis();
for (int i=0; i<SIZE; i++)
long e2 = System.currentTimeMillis();
System.out.println("endByException time:"+(e2-s2)+"ms" );
// Traverse arr Array : In an unusual way
private static void endByException(int[] arr) {
try {
int i=0;
while (true) {
//System.out.println("endByRange: arr["+i+"]="+arr[i]);
} catch (IndexOutOfBoundsException e) {
// Traverse arr Array : The way through the border
private static void endByRange(int[] arr) {
for (int i=0; i<arr.length; i++) {
//System.out.println("endByException: arr["+i+"]="+arr[i]);


Running results :
endByRange time:8ms
endByException time:16ms

The result shows that : The speed of traversing the array by exception is much slower than that of the normal way !

The first 2 strip : Use checked exceptions for recoverable conditions , Use runtime exceptions for program errors
• Runtime exception -- RuntimeException Classes and their subclasses are called runtime exceptions .
• Checked exceptions -- Exception Class itself , as well as Exception Except for " Runtime exception " Other subclasses are checked exceptions .

The difference is :Java The compiler will " Checked exceptions " Inspection , And yes " Runtime exception " Will not check . in other words , For checked anomalies , Either through throws Declare and throw , Either through try-catch Capture processing , Otherwise, it cannot be compiled . And for runtime exceptions , If " Don't pass throws Declaration throws it ", also " of no avail try-catch Statement capture it ", Still compile through . Of course , although Java The compiler does not check for runtime exceptions , however , We can also go through throws Explain the exception , Or through try-catch Capture .
ArithmeticException( for example , Divisor is 0),IndexOutOfBoundsException( for example , An array ) All belong to runtime exception . For this kind of abnormality , We should change the code to avoid it . And for the anomaly to be checked , The program can be resumed by processing . for example , Suppose that because a user doesn't store enough of the front , So his attempt to make a call on a pay phone will fail ; So it throws a checked exception .

The first 3 strip : Avoid unnecessary use of checked anomalies
" Checked exceptions " yes Java A good feature of language . Unlike return codes ," Checked exceptions " Conditions that force programmers to handle exceptions , Greatly improve the reliability of the program .
however , Overuse of checked exceptions can cause API It's very inconvenient to use . If a method throws one or more checked exceptions , Then the code calling the method must be in one or more catch These exceptions are handled in the statement block , Or you have to go through throws The statement throws these exceptions . Whether through catch Handle , Or through throws Declaration throws , Add a burden that can't be ignored to programmers .

Apply to " Checked exceptions " Two conditions must be met at the same time : First of all , Even if used correctly API It doesn't prevent the occurrence of abnormal conditions . second , Once something goes wrong , Use API The programmer can take useful actions to process the program .

The first 4 strip : Try to use standard exceptions
Code reuse is worth promoting , It's a general rule , Exceptions are no exception . There are several advantages to reusing existing exceptions :
First of all , It makes your API Easier to learn and use , Because it's consistent with idioms that programmers are already familiar with .
second , For the use of these API In terms of procedures , They're more readable , Because they won't be full of exceptions that programmers are not familiar with .
Third , The fewer exception classes , It means less memory usage , And the less time it takes to reprint these classes .

Java Several of the standard exceptions are frequently used . The following table :
┃ abnormal ┃ Use occasion ┃
┃ IllegalArgumentException │ The value of the parameter is not appropriate ┃
┃ IllegalStateException │ The state of the parameter is not appropriate ┃
┃ NullPointerException │ stay null When disabled, the parameter value is null ┃
┃ IndexOutOfBoundsException │ The subscript crossing the line ┃
┃ ConcurrentModificationException │ When concurrent modification is prohibited , Object detected concurrent changes ┃
┠───────────────────────────┼──────────── ─────────────────┨
┃ UnsupportedOperationException │ Object does not support methods requested by customers ┃
Although they are Java Platform library is by far the most frequently reused exception , however , With permission , Other exceptions can also be reused . for example , If you want to implement arithmetic objects like complex numbers or matrices , So reuse ArithmeticException and NumberFormatException It would be very appropriate . If an exception meets your needs , Don't hesitate , Just use it , However, you must make sure that the conditions under which the exception is thrown are consistent with those described in the exception's documentation . This reuse must be based on semantics , Not on the basis of names !
Last , Be sure to be clear about , There are no rules to follow when choosing which exception to reuse . for example , Consider the case of the card object , Suppose there is a method for licensing operations , Its parameters (handSize) It's the number of cards in a hand . Suppose the caller passes a value greater than the number of cards left in the deck . Then this situation can be interpreted as IllegalArgumentException(handSize It's worth too much ), It can also be interpreted as IllegalStateException( Relative to the customer's request , There are too few cards for the card object ).

The first 5 strip : The exception thrown should be appropriate for the corresponding abstraction
If a method throws an exception that has no obvious correlation with the task it performs , This situation can be overwhelming . When a method passes an exception thrown by a lower level abstraction , This often happens . When this happens , It's not just confusing , And also " Pollution " The high-level API.
To avoid this problem , High level implementations should catch lower level exceptions , At the same time, it throws an exception that can be introduced according to the high-level abstraction . This practice is known as " Abnormal translation (exception translation)".

for example , stay Java The collection framework of AbstractSequentialList Of get() The method is as follows ( be based on JDK1.7.0_40):
public E get(int index) {
try {
return listIterator(index).next();
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);

listIterator(index) Returns the ListIterator object , Calling the next() Method may throw NoSuchElementException abnormal . And in the get() In the method , Throw out NoSuchElementException Anomalies can be confusing . therefore ,get() Yes NoSuchElementException There was a catch , And throw IndexOutOfBoundsException abnormal . namely , Is equivalent to NoSuchElementException Translated into IndexOutOfBoundsException abnormal .

The first 6 strip : Every exception thrown by a method must be documented
To declare the checked exception separately , And make use of Javadoc Of @throws Mark , Accurately record the conditions under which each exception is thrown .
If many methods in a class throw the same exception for the same reason , Then document the exception in the document comment of this class , Instead of documenting each method individually , This is acceptable .

The first 7 strip : Include failure in detail message -- Capture the message
In short , When we customize an exception or throw an exception , It should contain information about the failure .
When a program fails due to an uncapped exception , The system will automatically print the stack trace of the exception . Contains the string representation of the exception in the stack trace . Typically, it contains the class name of the exception class , And the details that follow .

The first 8 strip : Try to keep failure atomic
When an object throws an exception , We always expect this object to remain in a well-defined, usable state . For the anomaly being checked , This is particularly important , Because callers usually expect to recover from the checked exception .
generally speaking , A failed method call should keep the object in " Its state before it is called ". This method has properties called " Failure atomicity (failure atomic)". It can be understood as , Failed and still atomic . The object remains " Failure atomicity " There are several ways :

(01) Design an immutable object .
(02) For methods that perform operations on mutable objects , get " Failure atomicity " The most common way is , Check the validity of the parameters before performing the operation . as follows ( Medium pop Method ):
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
(03) Similar to the previous method , You can adjust the order of the calculation process , Make any computation that may fail before the object state is modified .
(04) Write a recovery code , It explains the failures that occur during the operation , And roll back the object to the state it was in before the operation started .
(05) Perform operations on a temporary copy of an object , When the operation is completed, copy the results from the temporary copy to the original object .
although " Keep the failure atomicity of objects " It's the desired goal , But it doesn't always work . for example , If multiple threads attempt to synchronize without proper synchronization mechanism , Concurrent access to an object , Then the object may be left in an inconsistent state .

Even if it can be realized " Failure atomicity " The occasion of , It's not always expected . For some operations , It can significantly increase overhead or complexity .
The general rule is : As part of the method specification , Any exception should not change the state of the object before calling the method , If this rule is violated , be API The document should clearly indicate what state the object will be in .

The first 9 strip : Don't ignore exceptions
When one API When the designer of a method declares that a method will throw an exception , They're trying to explain something . therefore , Please don't ignore it ! The code to ignore exceptions is as follows :
try {
} catch (SomeException e) {

Empty catch Block will make the exception not achieve its intended purpose , The purpose of the exception is to force you to deal with abnormal conditions . Ignore an exception , It's like ignoring a fire signal -- If the fire alarm is turned off , So when a real fire happens , No one will see the fire signal . therefore , At least catch The block should contain a statement , It is appropriate to explain why this exception is ignored .

本文为[Half a month^]所创,转载请带上原文链接,感谢

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云