← Back to Core Java Course | Chapter 10: Exception Handling | Lesson 5 of 8

Java throw & throws

The throw Keyword

throw is a statement that actually raises a specific exception instance at the exact point you write it, immediately halting normal execution and searching for a handler.

Example: The throw Keyword

java
public class Main {
	public static void main(String[] args) {
		try {
			throw new IllegalArgumentException("Invalid input"); // raises it right here
		} catch (IllegalArgumentException e) {
			System.out.println(e.getMessage());
		}
	}
}

The throws Keyword

throws is a method-signature declaration, not a statement — it warns callers that this method might propagate a given checked exception, so the compiler can enforce that they handle or re-declare it.

Example: The throws Keyword

java
import java.io.IOException;
public class Main {
	static void readFile() throws IOException { // warns callers, doesn't throw yet
		throw new IOException("File error");
	}
	public static void main(String[] args) {
		try {
			readFile();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
}

throw vs throws

throw triggers one exception right now inside a method body; throws just documents in the method's signature which exceptions might come out of it. Confusing the two is a common beginner mistake since they look so similar.

Example: throw vs throws

java
public class Main {
	static void risky() throws Exception { // throws: documents in the signature
		throw new Exception("Something failed"); // throw: raises it now
	}
	public static void main(String[] args) throws Exception {
		risky();
	}
}

Exception Propagation

When a method doesn't catch an exception it could throw, that exception propagates up the call stack to whoever called it, and then to their caller, until something catches it or the program terminates with a printed stack trace.

Example: Exception Propagation

java
public class Main {
	static void level1() {
		level2();
	}
	static void level2() {
		throw new RuntimeException("Error at level2");
	}
	public static void main(String[] args) {
		try {
			level1(); // propagates up from level2 through level1
		} catch (RuntimeException e) {
			System.out.println("Caught: " + e.getMessage());
		}
	}
}

Best Practices with throw and throws

Only declare throws for exceptions a caller genuinely needs to know about and can meaningfully react to; throwing overly generic exceptions like plain Exception forces every caller into broad, less useful catch blocks.

Example: Best Practices with throw and throws

java
class InvalidAgeException extends RuntimeException { // specific, meaningful exception
	InvalidAgeException(String msg) { super(msg); }
}
public class Main {
	static void setAge(int age) {
		if (age < 0) {
			throw new InvalidAgeException("Age cannot be negative");
		}
	}
	public static void main(String[] args) {
		try {
			setAge(-5);
		} catch (InvalidAgeException e) {
			System.out.println(e.getMessage());
		}
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.