Does Java declare "throws Exception" by default?
There are two types of Exceptions: checked Exceptions (like ParseException
when parsing text) and unchecked Exceptions (like NullPointerException
).
Checked Exceptions must be declared in the method signature. Unchecked Exceptions may be declared in the method signature.
When overriding methods (from an interface or a super class) you only have to specify the exceptions, that you are throwing in your implementation. You cannot declare to throw checked exceptions in an implementation that are not allowed in the overridden method.
This is allowed:
class X { void someMethod() }
class Y extends X { @Override void someMethod() throws UncheckedException }
This is not allowed:
class X { void someMethod() }
class Y extends X { @Override void someMethod() throws CheckedException }
This is also allowed:
class X { void someMethod() throws CheckedException }
class Y extends X { @Override void someMethod() }
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
- Errors usually should not be caught, because they indicate serious problems. (e.g.
- There also is
RuntimeException
. This is a class extendingException
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();
}
}