Fear errors, but don't write them in Java! You probably already know a few things about exceptions in Java. Today, at least a superficial knowledge will benefit you. We're going to analyze the Error class and a special exception type that frightens many people when it appears in their stack traces.

At the top of Java's exception hierarchy is the Throwable class, which has two descendants:

  • Exception, which is responsible for errors in your program.
  • And our hero for today — Error, which is responsible for errors in the JVM.
    It is worth mentioning that these are probably not even coding bugs, but rather problems that usually do not depend on the developer.

What to do with an Error

When catching "errors", you cannot perform any actions in the catch block, except for logging, since we're talking about problems in the JVM itself.

Logging is good: when you get a runtime error, you can look at the logs, see its cause, and know what to fix.

Since you don't know what kind of error you might get when you write your code, it makes no sense to write a particular type in the catch block. Using the Error class itself is also not the best solution, since in this case, you will only catch errors.

Accordingly, it is better to use the Throwable class, which can catch both Error and Exception. How does this look in practice?

It's not OK to write code like this:
try {
    // Your code
} catch (OutOfMemoryError outOfMemoryError) {
    // Code to catch OutOfMemoryError
}
Writing code like this is also not OK:
try {
    // Your code
} catch (Error error) {
    // Code to catch all Errors
}
But code like this is OK:
try {
    // Your code
} catch (Throwable throwable) {
    // Code to catch all Throwables
}

The second option for handling errors is to throw them higher after declaring a throws clause on the method. This technique is used when your code could theoretically throw an error and you want to forewarn everyone who might use your code so that they can properly handle the error.

Common errors

Some of the most popular errors are the OutOfMemoryError and StackOverflowError classes.

OutOfMemoryError often appears when the program does not have enough memory to create objects and the garbage collector can't keep up. The result is an OutOfMemoryError.

Java doesn't let you manually delete objects to prevent memory leaks, but you can avoid littering so as to not overwork the garbage collector and not clutter up the heap.

For example, code like this will create a lot of garbage in memory:

while (true) {
    new Object();
}

The second error I want to tell you about is the StackOverflowError, which is thrown when the stack overflows. Since the stack mainly stores local variables, parameters, and method calls, recursion (or a recursive method call) is a very common cause of this error:

public void foo() {
    foo();
}

To avoid problems during program execution, modern IDEs often warn about calling methods recursively.

You can't fix a program that throws Errors, but you can write code that won't throw an error and break your program. Watch what you do with memory, create objects carefully, and call methods correctly. If you do that, then you will have fewer problems in your code.

Difference between the Error and Exception types

Error Exception
Cannot be corrected in catch block Can be handled in a catch block
Does not occur at compile time Can be caught at compile time
Problems in the JVM Problems in code logic
All Errors are unchecked checked and unchecked

You cannot escape exceptions in Java, but you should not be afraid of them. You just need to understand what each type represents and know how to handle it. That's all for today! See you!