Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Omitting throws declarations in derived classes

Consider the following interface:

public interface Generator {
    String generate() throws IOException;
}

and the following implementation:

public class EmptyStringGenerator implements Generator {
    @Override
    public String generate() {
        return "";
    }
}

Note that I omitted the throws IOException part of the signature specified in the Generator interface. Yet there is no compiler error, no compiler warning, not even the @Override annotation complains.

I am aware that this is working as intended. I would, however, like to know the intent behind this. If my method does not actually throw an IOException, it would be fine to just not throw it, I do not have to remove it from the signature. But if I do remove it from my method signature in EmptyStringGenerator, I am forcing all current and future subclasses of this class to forego the possibility of throwing an exception that is actually specified in the interface.

This, to me, sounds like a feature that does not really bring you any benefit (apart from saving a couple of keystrokes, which is not really a benefit at all), but has the potential to be a terrible mistake, when actually used.

So my question, effectively, is this: What is the point of omitting throws exceptions in derived classes? What is the problem that this possibility solves? Why is this allowed?

UPDATE

For people asking "but where is the harm in that?", here is my example from one of my comments. It is not far-fetched, by the way, because that is exactly what I am dealing with right now:

Programmer A specifies interface I. Programmer B writes implementation class X, but forgets to add the throws. He also never notices, because there is not even a warning being thrown here. Programmer C writes implementation class Y, inheriting from class X, he even specifically also wants to put the throws there, because he is gonna throw. But even though the interface stipulates it, he is now not allowed to do so anymore, because of B's oversight. He is effectively not allowed to use that exception here anymore. That's a pretty big harm. Especially if class X is not under your control.

like image 335
Jan Dörrenhaus Avatar asked Sep 11 '13 11:09

Jan Dörrenhaus


1 Answers

If you omit the throws exception in derived classes you can call the method of the derived class without having to catch the exception.

You make sure that subclasses of EmptyStringGenerator also don't throw an exception. Otherwise it would not be sure for the compiler if the method call can cause a checked exception which the code must handle. In that case the throws wouldn't make sense at all.

like image 109
Jimmy T. Avatar answered Oct 18 '22 09:10

Jimmy T.