John Tate
John Tate

Reputation: 772

Call constructor from constructor and catch exceptions

I have a constructor which calls another constructor in the same class. The problem is I want to catch Exceptions and throw them onwards to the method that called the first constructor. Yet Java doesn't allow this as the constructor call must be the first statement in the constructor.

public Config(String fn) throws IOException, ExcFormattingError {
    theFile = fn;
    try { cfRead(); }
    catch(FileNotFoundException e) {
        //create a new config with defaults.
        theConfig = defaultConfig();
        create();
    } catch (IOException e) {
        throw new IOException(e);
    } catch (ExcFormattingError e) {
        throw new ExcFormattingError();
    }

    fixMissing(theConfig);
}

public Config() throws IOException, ExcFormattingError {
    try {
        //Line below is in error...
        this("accountmgr.cfg");
    } catch (IOException e) {
        throw new IOException(e);
    } catch (ExcFormattingError e) {
        throw new ExcFormattingError();
    }
}

If someone could explain how I could do this that would be good. A bonus would be knowing why the language has to behave this way, because that is always interesting.

Upvotes: 3

Views: 1923

Answers (1)

Rohit Jain
Rohit Jain

Reputation: 213193

You don't need those try-catch block inside the constructor (in fact, you can't write it there, as you already figured out). So, change your constructor to:

public Config() throws IOException, ExcFormattingError {
    this("accountmgr.cfg");
}

In fact the catch block in your constructor was hardly doing anything productive. It was just re-creating an instance of the same exception, and throwing it. That is really not needed given the fact that, if the exception is thrown, it will automatically propagated to the caller code, where you can handle the exception.

public void someMethod() {
    Config config = null;
    try {
        config = new Config();
    } catch (IOException e) { 
        // handle it
    } catch (ExcFormattingError e) {
        // handle it
    }
}

Having said that, it is rarely a good idea to throw a checked exception from the constructor, even worse handling them in the caller code.
If the exception is thrown, and you handle it in the calling method. Then you are simply ignoring the fact that your instance is not completely initialized. Proceeding with that instance further will result in some unexpected behaviour. So, you should avoid it really.

Upvotes: 4

Related Questions