DIFFERENCE BETWEEN
THROW AND THROWS AND PARENT CLASS
OF EXCEPTIONS
I still remember the moment I realized I had been “half understanding” Java exception handling for years. Sure, my code compiled. Sure, I wrapped things in try catch blocks. But when senior engineers casually said, “Just throw it,” or “Add a throws declaration,” I just nodded like I knew exactly what was happening.
If you’ve been there too, don’t worry. Let’s straighten this out.
throw vs throws — They Look Similar, but They Don’t Play the Same Role
Think of exceptions like messages you pass when something goes wrong. Now imagine Java giving you two different tools to deliver that message.
`throw` — You actually throw the exception inside your code
This is the moment your code says: “I can’t do this. I’m passing the problem upward.” You use it when you want to create an exception yourself.
Example
public void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18+");
}
System.out.println("Allowed");
}Here, you manually throw the exception. throw = create and throw an exception object right now.
`throws` — Just declaring that this method might throw something
You’re basically telling callers: “Hey, I’m not solving this error here. If something breaks, it’s your job to handle it.”
Example
public void readFile() throws IOException {
Files.readAllLines(Path.of("data.txt"));
}
The method doesn’t handle the IOException. It just declares it.
throws = promise that this method might throw these exceptions.
Quick Reality Check
When you write:
public void doSomething() throws Exception { }You're not throwing anything yet. You’re only giving a warning label.
When you write:
throw new Exception("Boom");Now you're actually causing something to blow up.
The Exception Family Tree (Why This Matters)
Most Java learners memorize this hierarchy, but understanding why it exists is what gives you superpowers.
Here's the simplified family:
Throwable
├── Error
└── Exception
├── RuntimeException
└── (other checked exceptions)Let’s break it into real developer terms.
Error — Problems you should not handle
Think: OutOfMemoryError and StackOverflowError
They mean: “The JVM is crying. Your app can’t recover.”
You almost never try to catch these. Treat them like earthquakes, you don’t control them.
Exception — Problems you can and should handle
Exceptions come in two flavors:
1. Checked Exceptions
These are the “responsible adults.” They force you to handle them or declare them with throws.
Examples: IOException, SQLException and FileNotFoundException
Java stops compilation unless you handle them:
public void load() throws IOException { }2. Runtime Exceptions (Unchecked)
These are the “wild kids”. They can happen anytime and don’t require a throws declaration.
Examples: NullPointerException, IllegalArgumentException, ArithmeticException
You can write this freely:
public void doMath() {
int result = 10 / 0; // runtime exception
}A Realistic Sample
Here’s code that uses all concepts clearly:
public class FileProcessor {
// This method DECLARES it might throw a checked exception
public void process() throws IOException {
String content = readFile();
validate(content);
}
// Method that might throw a checked exception
private String readFile() throws IOException {
return Files.readString(Path.of("data.txt"));
}
// Method that THROWS a runtime exception manually
private void validate(String text) {
if (text == null || text.isEmpty()) {
throw new IllegalArgumentException("File content cannot be empty");
}
}
}Breakdown:
- check_circle process() has throws IOException → checked exception
- check_circle readFile() also throws IOException
- check_circle validate() manually throw new IllegalArgumentException() → runtime exception
This is the sort of code you write every day. Now you know exactly what each part does.
Final Thoughts
Mastering throw vs throws isn’t about memorizing definitions. It’s about understanding who handles the problem and where responsibility moves.
- check_circle throw = Trigger an exception right now.
- check_circle throws = Declare that this method might throw something.
- check_circle Exception = Recoverable problems.
- check_circle RuntimeException = Unchecked mistakes in your logic.
- check_circle Error = “JVM is dying, please pray.”
Once this clicked for me, debugging and designing clean APIs became way easier.
Hopefully, this explanation gives you the same clarity.