mittelmania
mittelmania

Reputation: 3561

Using exception handling to eliminate irrelevant exceptions in subclass constructor

I'm writing a class in Java which is a subclass of another class I wrote, and its constructor explicitly calls the superclass's constructor. The constructor of the superclass may throw several types of exceptions when initialized directly, however when I initialize an instance of my subclass there are several exceptions that will never by thrown (by design).

I tried catching these exceptions in the subclass's constructor but I received an error stating that "Constructor call must be the first statement in a constructor". Why can't I catch these exceptions?

For example, the code below:

public class Persian_Cat extends Cat {

    public Persian_Cat(File file) {
        try{
            super(file);
        } catch(InvalidArgumentException e) {
        } catch(FileNotFoundException e) {
        }
    }
}

marks the statement super(file); as the error.

How can I implement the subclass constructor so that it will know these exceptions are irrelevant? I need this because I don't wish to wrap this constructor in try{}...catch{} for every exception in my code later.

Upvotes: 6

Views: 161

Answers (2)

Elliott Frisch
Elliott Frisch

Reputation: 201447

If your first line isn't an explicit super constructor call then the JVM will insert an empty one. So if you need to invoke a non-empty super constructor it must be the first line.

public Persian_Cat(File file) throws InvalidArgumentException,
    FileNotFoundException  {
  super(file);
}

JLS-8.8.7 reads (in part),

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

So when you ask Why can't I catch these exceptions? The answer is that Java doesn't provide a mechanism to do so. You can mark the Persian_Cat constructor as throwing them too. Or you could create another constructor that doesn't throw the Exception(s) or add a File setter to the super type. Or perhaps you need a Builder or a Factory.

Upvotes: 1

Duncan Jones
Duncan Jones

Reputation: 69339

Sadly, if you use super(...); it must be the very first line of code in the constructor. There is no way to avoid this.

One solution would be to create another constructor that doesn't throw those exceptions. It may be sensible to scope this as protected, rather than public. You would want to document the API to make it clear which input validation (or whatever) is not being conducted because of which assumptions.

Upvotes: 6

Related Questions