Java Tutorial
Java Exceptions
throw signals a failure. try and catch recover without scattering error codes through every call.
throw, try, catch
throw new IllegalArgumentException("...") stops the method and hands control to the nearest matching catch. Use exceptions for “this should not happen” paths — bad input, missing data — instead of magic return codes.
Example
public class Main {
static int positive(int n) {
if (n < 0) throw new IllegalArgumentException("need a positive number");
return n;
}
public static void main(String[] args) {
try {
System.out.println(positive(-1));
} catch (Exception err) {
System.out.println(err.getMessage());
}
}
}finally always runs
A finally block runs whether the try succeeded or threw — useful for cleanup. Prefer try-with-resources for files and scanners so closing is automatic.
Example
public class Main {
public static void main(String[] args) {
try {
int n = Integer.parseInt("oops");
System.out.println(n);
} catch (NumberFormatException e) {
System.out.println("not a number");
} finally {
System.out.println("done");
}
}
}Catch the specific type
Catch the narrowest exception you can handle. Multiple catch blocks are tried in order — put subclasses before superclasses.
Example
public class Main {
public static void main(String[] args) {
String[] words = {"hi"};
try {
System.out.println(words[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("bad index");
} catch (Exception e) {
System.out.println("other: " + e);
}
}
}Catching bare Exception is fine at the top of main for demos. In libraries, catch what you can fix and let the rest propagate.
Checked vs unchecked
IOException is checked: you must catch it or declare throws.IllegalArgumentException and NullPointerException are unchecked(runtime). These lessons use unchecked errors for bad values, and throws Exception on main for file demos.
Example — declare throws
import java.io.IOException;
import java.nio.file.*;
public class Main {
static String load(String name) throws IOException {
return Files.readString(Path.of(name));
}
public static void main(String[] args) throws IOException {
System.out.println(load("note.txt"));
}
}Do not swallow exceptions with an empty catch. At least log or print the message — silent failure is worse than a crash you can see.
Try It Yourself
Exercise: Write a method half(int n) that throws IllegalArgumentException if n is odd, otherwise returns n / 2. Call it from main inside try/catch.
Show solution
static int half(int n) {
if (n % 2 != 0) throw new IllegalArgumentException("need even");
return n / 2;
}
// in main:
try {
System.out.println(half(7));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}Odd input hits throw; the catch prints the message instead of crashing the whole program.
Key Takeaways
throwsignals failure;try/catchrecover at a chosen level.finally(or try-with-resources) runs cleanup whether or not an error occurred.- Checked exceptions must be caught or declared; unchecked need not be.
- Catch specific types first; never leave an empty catch that hides bugs.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the Java editor at /java/try. Change one measurement and check whether the result still has the right unit.
Engineering
Guard a negative reading
A sensor that reports a negative current is broken, not just quiet. throw stops the bad value from spreading. catch prints the reason.
Example
public class Main {
static double current(double amps) {
if (amps < 0) throw new IllegalArgumentException("current cannot be negative");
return amps;
}
public static void main(String[] args) {
try {
System.out.println(current(-0.2));
} catch (Exception err) {
System.out.println(err.getMessage());
}
}
}