What slartidan said in their answer is fully correct. To explain a little more:
If you are throwing a "Checked Exception" inside the body of a method, you are required to either handle it (using a catch-block) or to declare a throws-clause
To reiterate the previously linked JLS:
- An Exception is a class extending
Throwable
- An Error also is a class extending
Throwable
- Errors usually should not be caught, because they indicate serious problems. (e.g.
OutOfMemoryError
)
- catching
Exception
does not catch Errors
- There also is
RuntimeException
. This is a class extending Exception
Errors and Runtime Exceptions are not checked at compile time, because that exactly is what "checked exception" means.
You may throw Error
s and RuntimeException
s anywhere in your code.
Now how does this affect throws clauses:
A throws clause specifies that an invocation of the declared method may result in the exception specified. Interestingly throws expects a Throwable
, which makes following declaration valid:
public void method() throws StackOverflowError, NullPointerException {
//...
}
There is no compiler effect when declaring non-checked Exceptions in a throws clause, but it's sometimes done for additional clarity in your sourcecode.
Additionally such Exceptions are sometimes mentioned in JavaDoc (e.g. BigInteger#divide
)
But the compiler checks the throws clause when overriding methods. It's somewhat similar to the visibility rules when overriding methods. This means throwing unchecked Exceptions (and declaring corresponding throws clauses) can always be done. Following declaration is valid:
public interface Demo {
void test();
}
public class DemoImpl implements Demo {
public void test() throws NullPointerException {
throw new NullPointerException();
}
}
It's the same the other way round. Unchecked exceptions in throws clauses are disregarded by the compiler, because they aren't relevant to compile-time checking:
public interface Demo {
void test() throws NullPointerException;
}
public class DemoImpl implements Demo {
public void test() {
throw new NullPointerException();
}
}
The general rule for throws-clause inheritance is: One interface to rule them all: The interface must declare all checked exceptions that can be thrown by implementing classes. Or in other words:
Implementing classes may declare a subset of the declared checked Exceptions in the interface method's throws-clause in the throws-clause of the implementing method
This means following is valid:
public interface Demo {
void test() throws IOException, ParseException;
}
public class DemoImpl implements Demo {
public void test() throws IOException {
throw new IOException();
}
}
What's not valid is declaring a checked exception in the implementing method's throws-clause that's not declared in the corresponding interface method's clause:
public interface Fail {
void test() throws ParseException;
}
public class FailImpl implements Fail {
public void test() throws IOException {
throw new IOException();
}
}
try-with-resources
) – TheLostMindNullPointerException
is aRuntimeException
and doesn't need athrows
clause. – Mark RotteveelRuntimeException
and the exceptions that extend it. – EpicPandaForceclass
cant throw exception. – Kartic