Java exception handling practices

Source: Internet
Author: User
Tags finally block sql error
Do you think you are a Java expert? Are you sure you have fully mastered the Java exception handling mechanism? In the following code, can you quickly find the six problems for exception handling?


1 outputstreamwriter out =...
2 Java. SQL. Connection conn =...
3 try {// retry
4 Statement stat = conn. createstatement ();
5 resultset rs = stat.exe cutequery (
6 "select uid, name from user ");
7 while (Rs. Next ())
8 {
9 out. println ("ID:" + Rs. getstring ("uid") // response
10 ", name:" + Rs. getstring ("name "));
11}
12 conn. Close (); // (3)
13 out. Close ();
14}
15 catch (exception ex) // (2)
16 {
17 ex. printstacktrace (); // (1), (4)
18}

As a Java programmer, you should be able to identify at least two problems. However, if you cannot find all six questions, read this article.

This article does not discuss general principles of Java Exception Handling, because these principles are well known to most people. What we need to do is to analyze common bad habits that can be called "anti-pattern" (Anti-pattern) against excellent coding specifications and help readers familiarize themselves with these typical negative examples, in this way, you can perceive and avoid these problems keenly in your actual work.

  Counterexample: discard exception

Code: Lines 15-18.

This code captures exceptions without any processing. It can be regarded as a killer in Java programming. In terms of the frequency and severity of the problem, it may be comparable to that of the C/C ++ program ?? Do not check whether the buffer zone is full. If you see this discard (rather than throw) exception, you can be 99% sure that the code is faulty (in rare cases, this code has a reason, but it is best to add a complete comment to avoid misunderstanding ).

The error in this Code is that exceptions (almost) always mean something is wrong, or at least something unusual happens, we should not remain silent or indifferent to the distress signals sent by the program. Calling printstacktrace does not count as "Exception Handling ". Yes. Calling printstacktrace is helpful for debugging programs. However, after the program debugging stage ends, printstacktrace should no longer take the primary responsibility in the Exception Handling Module.

Discard exceptions are common. Open the JDK threaddeath class document and you can see the following description: "In particular, although threaddeath is a 'normal situation ', the threaddeath class is a subclass of error rather than exception, because many applications capture all exceptions and discard them." This section indicates that, although threaddeath represents a common problem, many applications attempt to capture all exceptions and then do not handle them properly, therefore, JDK defines threaddeath as a subclass of error, because the error class represents a serious problem that general applications should not capture. It can be seen that the habit of dropping exceptions is so common that it has even affected Java's design.

So how should we correct it? There are four main options:

1. handle exceptions. Actions should be taken to fix the exception, such as correcting the problem, reminding a person or performing other actions according to the specific situation. Again, calling printstacktrace does not count as "handled exceptions ".

2. Throw an exception again. After analyzing an exception, the code that handles the exception considers itself unable to handle it, and throwing an exception again is also an option.

3. Convert the exception to another exception. In most cases, this refers to converting a low-level exception to an application-level exception (which means exceptions that are more easily understood by users ).

4. Do not capture exceptions.

Conclusion 1: as exceptions are captured, appropriate processing is required. Do not discard an exception and ignore it.

  Counterexample 2: do not specify a specific exception

Code: 15 lines.

In many cases, people will be attracted by such a "wonderful" idea: Catch all exceptions with a catch statement. The most common case is to use catch (exception ex) statements. But in fact, in most cases, this approach is not worth advocating. Why?

To understand the cause, we must review the usage of the catch statement. The catch statement indicates that we expect an exception and want to handle it. The function of the exception class is to tell the Java compiler which exception we want to handle. Since most exceptions are derived directly or indirectly from Java. Lang. exception, catch (exception ex) is equivalent to saying that we want to handle almost all exceptions.

Let's take a look at the previous code example. What exceptions do we really want to capture? The most obvious one is sqlexception, which is a common exception in JDBC operations. Another possible exception is ioexception because it needs to operate outputstreamwriter. Obviously, it is not appropriate to handle these two distinct exceptions in the same Catch Block. If two catch blocks are used to capture sqlexception and ioexception respectively, it is much better. That is to say, the catch statement should specify the exception type as much as possible, instead of the exception class with a wide scope.

On the other hand, in addition to these two specific exceptions, many other exceptions may also occur. For example, what if executequery returns NULL for some reason? The answer is to let them continue to throw, that is, they do not need to be captured or processed. In fact, we cannot and should not capture all possible exceptions. Are there other opportunities for programs to capture exceptions ?? Until it is finally processed by JVM.

Conclusion 2: Specify the exception type as much as possible in the catch statement, and use multiple catch when necessary. Do not try to handle all possible exceptions.

  Counterexample 3: Do not release occupied Resources

Code: 3-14 lines.

An exception changes the normal execution process of the program. Although this principle is simple, it is often ignored. If the program uses resources such as files, sockets, and JDBC connections, the occupied resources should be correctly released even if an exception occurs. Therefore, Java provides a keyword finally to simplify such operations.

Finally is a good thing: whether or not an exception occurs, finally ensures that the code for executing the cleanup task will always have a chance to execute before the try/catch/Finally block ends. Unfortunately, some people are not used to using finally.

Of course, you should be careful when writing finally blocks, especially the exceptions thrown in finally blocks ?? This is the last chance to execute the cleanup task. Try not to handle any difficult errors.

Conclusion 3: Ensure that all resources are correctly released. Make full use of finally keywords.

  Counterexample 4: Detailed exception information is not described

Code: 3-18 rows.

Observe this code carefully: if an exception occurs inside the loop, what will happen? Can we get enough information to determine the cause of internal errors in the loop? No. We can only know that the currently being processed class has an error, but cannot obtain any information to determine the cause of the current error.

The stack trace function of printstacktrace shows the execution process from the program running to the current class. However, it only provides some basic information and does not explain the cause of the error.

Therefore, when an exception occurs, it is best to provide some text information, such as the class, method, and other status information currently being executed, includes organizing and organizing the information provided by printstacktrace in a more appropriate way.

Conclusion 4: The error cause information is provided in the exception handling module, which is easy to understand and read.

  Example 5: Too large try Blocks

Code: 3-14 lines.

It is often seen that a large amount of code is put into a single try block. In fact, this is not a good habit. This phenomenon is common because it is easy for some people to figure out which lines of code in a large piece of code will throw exceptions and the specific types of exceptions. Loading a large number of statements into a single try block is like inserting all the daily necessities into a large box when traveling. Although things are carried, it is not easy to find them.

Some new users often put a large amount of code into a single try block, and then declare the exception in the catch statement, instead of separating the sections that may encounter exceptions and capturing their exceptions separately. This method makes it difficult for the analysis program to throw an exception because there are too many parts of the Code that may throw an exception.

Conclusion 5: try to minimize the volume of try blocks.

  Counterexample 6: incomplete output data

Code: Lines 7-11.

Incomplete data is the invisible killer of Java programs. Observe the code carefully and consider what will happen if an exception is thrown in the middle of the loop. Of course, the execution of the Loop will be interrupted. Secondly, the catch block will be executed ?? There are no other actions. What should I do if I have output data? The person or device using the data will receive an incomplete (and thus incorrect) data, but will not receive any prompt about whether the data is complete. For some systems, incomplete data may cause greater losses than stopping the system.

The ideal solution is to write some information to the output device to declare the data integrity. Another effective method is to buffer the data to be output first, prepare all the data and output the data at a time.

Conclusion 6: the possible exceptions and their impact on the execution process should be fully considered.

  Modified code

Based on the above discussion, the revised code is given below. Maybe someone will say it is a little bit? But it has a complete exception handling mechanism.


Outputstreamwriter out =...
Java. SQL. Connection conn =...
Try {
Statement stat = conn. createstatement ();
Resultset rs = stat.exe cutequery (
"Select uid, name from user ");
While (Rs. Next ())
{
Out. println ("ID:" + Rs. getstring ("uid") + ", name:" + Rs. getstring ("name "));
}
}
Catch (sqlexception sqlex)
{
Out. println ("Warning: incomplete data ");
Throw new applicationexception ("SQL error occurred when reading data", sqlex );
}
Catch (ioexception ioex)
{
Throw new applicationexception ("I/O error occurred when writing data", ioex );
}
Finally
{
If (Conn! = NULL ){
Try {
Conn. Close ();
}
Catch (sqlexception sqlex2)
{
System. Err (this. getclass (). getname () + ". mymethod-The database connection cannot be closed:" + sqlex2.tostring ());
}
}

If (OUT! = NULL ){
Try {
Out. Close ();
}
Catch (ioexception ioex2)
{
System. Err (this. getclass (). getname () + ". mymethod-the output file cannot be closed" + ioex2.tostring ());
}
}
}

The conclusion in this article is not a well-founded dogma. Sometimes common sense and experience are the best teachers. If you do not have a hundred percent confidence in your practice, you must add a detailed and comprehensive comment.

On the other hand, don't laugh at these mistakes. Ask yourself if you have completely escaped these bad habits. Even the most experienced programmers occasionally go astray for a simple reason, because they actually bring "convenience ". All these examples can be seen as the demons of the Java programming world. They are beautiful and pervasive, and they will always seduce you. Some people may think that these are all trivial matters of chicken skin, garlic, and hair, but please remember: do not be evil, do not be good or small.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.