Exception Handling with Method Overriding and Constructors in Java - Quiz

Total: 5 questions

1. 

Which exceptions can an overriding method declare in throws in Java, and why does this restriction exist?

An overriding method may declare the same checked exceptions as the superclass method, their subclasses, or nothing at all; it may add any unchecked exceptions. If the parent declares void start() throws IOException, the subclass may use throws IOException, throws FileNotFoundException, no throws clause, or throws IllegalArgumentException, while throws Exception (a broader type) and throws SQLException (an unrelated type) fail with overridden method does not throw Exception. The rule protects polymorphic code: a method that calls obj.start() through a superclass reference and catches only IOException must not receive an unhandled checked exception from a subclass. A subclass may promise less than its parent, never more.

2. 

Which exceptions must a subclass constructor declare if the superclass constructor has a throws clause, and can they be caught around super()?

A subclass constructor always invokes a superclass constructor, explicitly through super(...) or implicitly, so it must declare every checked exception of that constructor with the same type or a superclass. For SuperClass() throws IOException, SubClass() throws IOException, throws Exception and throws IOException, SQLException all compile: a constructor may add new checked exceptions. throws FileNotFoundException (a subclass does not cover every case), a constructor without throws and no constructor at all fail: unreported exception IOException in default constructor. The exception cannot be caught: super(...) cannot be placed inside try, even in Java 25 with Flexible Constructor Bodies (JEP 513). The way out is to call another superclass constructor or to create the object through a factory method.

3. 

Why can't Runnable.run() declare throws IOException, and how do you handle an IOException inside run()?

The overriding rule also applies to interface methods: a class method cannot declare a checked exception that is missing from the throws clause of the interface method. Runnable.run() declares nothing, so public void run() throws IOException fails with run() in FileTask cannot implement run() in Runnable; overridden method does not throw IOException. The same goes for Comparator.compare(), Object.toString() and Consumer.accept() in lambdas. Handle the exception in place or wrap it in an unchecked one, keeping the cause: catch (IOException e) { throw new UncheckedIOException(e); } (available since Java 8); for other types use throw new RuntimeException(e). An empty catch is not an option: the error would disappear without a trace.

4. 

Why remove throws Exception when implementing AutoCloseable.close()?

The interface declares void close() throws Exception, and try-with-resources calls close() automatically, so the surrounding code must handle every exception from its throws clause. If the implementation keeps close() throws Exception, the block try (DbSession s = new DbSession()) { ... } without catch does not compile: unreported exception Exception; must be caught or declared to be thrown. An overriding method is allowed to narrow the exception list, so if the resource throws no checked exceptions on closing, write public void close() without throws — and try-with-resources with this class no longer requires catch (Exception e). You can also narrow it to a specific type, for example close() throws IOException.

5. 

A subclass removed throws from an overridden method. Why does the compiler still require try-catch when the method is called through a superclass reference?

Checking throws is the job of the compiler, not the JVM: it decides which exceptions must be handled by the declared (static) type of the variable, not by the actual object. If Parser.parse() declares throws IOException and StrictParser.parse() overrides it without throws, then strict.parse("a") through a StrictParser reference compiles without try-catch, while the same object through Parser p = strict requires catch (IOException e). At run time the method of the actual object is called in both cases. That is why narrowing throws in a subclass is useful: code that works with the concrete class gets rid of unnecessary try-catch blocks.

Page 1 of 1