C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Step 1: We cause an exception on purpose—we divide by zero. This statement is inside a try block.
Step 2: The ArithmeticException, derived from Exception, is matched by the Exception catch clause. We then display the exception.
Note: In this example, the Exception base class is used. The exception is of type ArithmeticException.
Java program that uses try, catch
public class Program {
public static void main(String[] args) {
try {
// Step 1: divide by zero.
int value = 1 / 0;
} catch (Exception ex) {
// Step 2: display exception.
System.out.println(ex);
}
}
}
Output
java.lang.ArithmeticException: / by zero
Java program that causes NullPointerException
public class Program {
public static void main(String[] args) {
// An input string.
String name = "sam";
System.out.println(name.length());
// When string is null, an exception occurs.
name = null;
System.out.println(name.length());
}
}
Output
3
Exception in thread "main" java.lang.NullPointerException
at program.Program.main(Program.java:9)
Java Result: 1
Program 1: We see a program that fails compilation. It cannot be executed. A java.lang.Error is reported.
Program 2: This program adds the "throws Exception" clause. It now executes correctly—it throws the Exception during runtime.
Java program that causes compilation error
public class Program {
public static void main(String[] args) {
throw new Exception();
}
}
Output
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type Exception
at program.Program.main(Program.java:5)
Java program that has no compilation error
public class Program {
public static void main(String[] args) throws Exception {
throw new Exception();
}
}
Output
Exception in thread "main" java.lang.Exception
at program.Program.main(Program.java:5)
Java program that uses finally block
public class Program {
public static void main(String[] args) {
String value = null;
try {
// This statement causes an exception because value is null.
// ... Length() requires a non-null object.
System.out.println(value.length());
} catch (Exception ex) {
// This runs when the exception is thrown.
System.out.println("Exception thrown!");
} finally {
// This statement is executed after the catch block.
System.out.println("Finally done!");
}
}
}
Output
Exception thrown!
Finally done!
Caution: Unless an exception may occur, this is not a worthwhile construct. In more complex programs, "finally" makes more sense.
Java program that uses finally without exception
public class Program {
public static void main(String[] args) {
try {
System.out.println("In try");
} finally {
// The finally is run even if no exception occurs.
System.out.println("In finally");
}
System.out.println("...Done");
}
}
Output
In try
In finally
...Done
Tip: In my experience, stack overflow is often caused by incorrect recursive calls.
Tip 2: A program, like the one here, can cause a StackOverflowError just by using unchecked recursion.
RecursionJava program that encounters StackOverflowError
public class Program {
static void applyRecursion() {
applyRecursion();
}
public static void main(String[] args) {
// Begin recursion.
applyRecursion();
}
}
Output
Exception in thread "main" java.lang.StackOverflowError
at program.Program.applyRecursion(Program.java:6)
at program.Program.applyRecursion(Program.java:6)
at program.Program.applyRecursion(Program.java:6)...
Version 1: In this version of the code, we use an if-statement to prevent any exceptions from occurring.
Version 2: Here we just divide, and handle exceptions in a catch block if we cause an error.
Result: Checking for zero and preventing a division error is faster than handling errors in a try and catch clause.
Java program that benchmarks exceptions
public class Program {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
// Version 1: check against zero before division.
for (int i = 0; i < 1000000; i++) {
int v = 0;
for (int x = 0; x < 10; x++) {
if (x != 0) {
v += 100 / x;
}
}
if (v == 0) {
System.out.println(v);
}
}
long t2 = System.currentTimeMillis();
// Version 2: handle exceptions when divisor is zero.
for (int i = 0; i < 1000000; i++) {
int v = 0;
for (int x = 0; x < 10; x++) {
try {
v += 100 / x;
} catch (Exception ex) {
// Errors are encountered.
}
}
if (v == 0) {
System.out.println(v);
}
}
long t3 = System.currentTimeMillis();
// ... Times.
System.out.println(t2 - t1);
System.out.println(t3 - t2);
}
}
Output
36 ms: if-check
89 ms: try, catch
But: Other alternatives exist. We can use a special, "null object" instance that handles method calls with no errors.
Tip: The "null object" design pattern is described in the book Refactoring. It eliminates many branches in code.