3

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.

John Tate
  • 780
  • 3
  • 10
  • 23
  • 3
    Why are you catching the exceptions at all? If you don't catch them they'll just go back out to whoever called the first constructor. – Chris Hayes Sep 22 '13 at 17:57
  • See http://stackoverflow.com/a/1168356/1729686 for why `this()` and `super()` need to be called first. – Liam Sep 22 '13 at 18:05

1 Answers1

4

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.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525