11 Mistakes Java Developers make when Using Exceptions

The problem: If you use Exceptions in the wrong way, bugs will be very difficult to find. If you always use generic Exceptions, how can other developers know what error has occurred? You have to understand why we use Exceptions and how to use them effectively!

See the 11 mistakes Java Developers make when using Exceptions.

First, let’s see the hierarchy of the Exception classes.

Checked Exceptions / Unchecked Exceptions

1 – Using only the Exception class

It’s a common mistake that developers specifically catch the Exception class for any error. It’s much more difficult to identify the error if you see only an Exception being caught. The solution to this problem is to create specific Exceptions – but watch out, not too specific!

2 – Creating lots of specific Exceptions

Don’t create Exceptions for everything. Your application will be full of classes, useless repetition and you will create unnecessary work. Instead, create Exceptions for really important business requirements. For example, if you are developing a bank system one possible Exception would be when trying to withdraw money and the balance is zero: BalanceNotAvailableException. Another Exception would be transferring money to another person and the account does not exist, you can create: BankAccountNotFoundException and show an understandable Exception message to the user.

RuntimeException could be used when the bank’s server is out of service. Here you can use, for example: ServerNotAvailableException. The system must crash for this kind of error. There is no recovery.

3 – Creating a log for every catch

Logging every Exception catch will pollute your code. To prevent this, just log once and throw your Exception in the last catch. You won’t lose your Stacktrace if you wrap the Exception. If you are working with web applications, you should create a catch on your controller layer and log the error.

4 – Not knowing the difference between Checked and Unchecked Exceptions

When should Checked Exceptions be used? Use Checked when there is a recoverable error or an important business requirement.

The most common Checked Exception is the Exception class. Two related classes from Exception are FileNotFoundException and SQLException.You are obligated to handle or declare these exceptions. You must throw or catch the Exception or else it won’t compile.

When should Unchecked Exceptions be used? Use Unchecked when there is no recovery. For example, when the memory of the server is overused.

RuntimeException is used for errors when your application can not recover. For example, NullPointerException and ArrayOutOfBoundsException. You can avoid a RuntimeException with an ‘if’ command. You should not handle or catch it.

There is also the class Error. It is an Unchecked Exception too. Never try to catch or handle this kind of Exception. They are errors from the JVM and are the most serious kind of Exception in Java. You must analyze the cause of Exceptions like this and change your code.

5 –  Silencing Exceptions

Never catch the Exception and do nothing, for example:

try {
    System.out.println("Never do that!");
} catch (AnyException exception) {
    // Do nothing
}

The catch will be useless. It’s impossible to know what happened and the Exception will be silenced. The developer will be obliged to debug the code and see what happened. If we create a good log, the time-consuming analysis won’t be necessary.

6 – Not following the principle “throw early, catch late”

If you have to handle Exception, for example, in your Service, you should do two things:

  1. Wrap your Exception
  2. Throw the Exception to the last catch and handle it.

7 – Not using clear messages on the Exceptions

Always use clear messages on your Exceptions. Doing this will help a lot when finding errors. Even better, create a Properties File with all Exception messages. You can use the file on your View layer and show users messages about the business requirements.

8- Not cleaning up after handling the Exception

After using resources like files and database connection, clean them and close them so that you won’t harm the system’s performance. You can use the finally block to do it.

9 – Not documenting Exceptions with javadoc

To avoid headaches, always Document why the Exception is being thrown in your method. Document your Exception and explain why you created it.

10 – Never lose the Stacktrace

When wrapping an Exception in another one, don’t just throw the other Exception, keep the Stacktrace.

Bad code:

try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException();
}

Good code:

try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException(exception);
}

11 – Not organizing the hierarchy of specific Exceptions

If you don’t organize the hierarchy of your Exceptions, the relationship will be difficult between the parts of the system. You will have lots of problems.

You should use an hierarchy similar to this one:

                                                                                     Exception

BusinessException

AccountingException

HumanResourcesException
BillingCodeNotFoundException

  EmployeeNotFoundException

11 Mistakes Java Developers make when Using Exceptions

5 Great Programming Techniques Every Developer Should Know

1 – Encapsulate ifs inside their methods, not outside them:

Bad example:


If (value > 500) {

     applyDiscountForGreaterThan500();

} else if (value > 1000) {

     applyDiscountForGreaterThan1000();

}

Good example:

// encapsulated ifs in the methods 

applyDiscountIfValueIsGreaterThan500(); 

applyDiscountIfValueIsGreaterThan1000();

2 – Stop a moment to think about the name of the package/class/method/variable

YES, names are EXTREMELY important.

With a self-describing name, it is very easy to find out what your code is doing.

For this reason, do not use the first name that pops into your head. Think about the best possible name that describes exactly for what your package, class, method, variable is responsible.

Avoid ambiguous names! If a bug occurs in this functionality, it will be very difficult to find it.

Examples of ambiguous names:

 Double clientValue; // Value of the client, value of what?

 void hide() // What does that hide?

 class Historic {} // Historic of what? Historic for everything? 
  //Where is the cohesion? 

Specific names help A LOT!

3 – Get to know the shortcuts of your IDE

I am going to use Eclipse’s example. It’s very important to use the shortcuts so you can code two or three times faster.

Control + 3 = “Eclipse’s Google” – write “new class” for example.

Control + shift + F = format your code.

Control + 1 = do various actions. For example, invoke a method that does not exist yet and use the shortcut.

Alt + up = moves a line of code to the above line.

Control + shift + R = search any archive you want on your project.

Control + H = search any word you want on your project.

Alt + Shift + R = rename any package, class, method, variable and update all the references.

Configure Eclipse’s formatter. Change it from 80 characters per line to 120. Configure save actions too so you can have actions when you save your code on Eclipse. For example, we can use the command “organize imports” after each save.

There are many other shortcuts, but remember, you need to use them until they get automatic for you. If you forgot to use the shortcut, undo what you did without using the shortcut and then, do the same thing using the shortcut, so you’ll never forget it. For example, if you are going to delete a code line and you forget to use the shortcut, just undo it and use the shortcut control + D.

More sources:

Eclipse Shortcuts

Netbeans Shortcuts

IntelliJ Shortcuts

4 – Encapsulate methods for what you need

Have you noticed a lot of code in your application that does the same thing?

Why not encapsulate a method for this?

For example:

Calendar c = Calendar.getInstance();

c.setTime(new Date());

c.add(Calendar.DATE, +1);

Date userDate = c.getTime();

It would be a lot easier and much clearer to encapsulate all this code in a separated class and method:

Date nextDay = DateUtils.getNextDay();

Consider if need to keep state of your object, if so, instantiate it!

Remember, the most important thing here, is to encapsulate your solution!

5 – Create the culture of Code Review in your company

Even if the company you work for doesn’t use a Code Review tool, ask your friend to take a look at your code.

Each developer has his own experiences. We can learn a lot by sharing them.

Many things that you may not have noticed in a simple Code Review could be uncovered in a peer Code Review. You will see your mistakes and learn from them!

Follow me on Twitter to learn more great programming techniques. I will be sending a new one each week!

For learning new techniques every week, subscribe here on NoBugsProject email list!

Remember, practicing these techniques will make you an even greater developer.

5 Great Programming Techniques Every Developer Should Know