从构造函数调用构造函数并捕获异常

时间:2013-09-22 17:56:01

标签: java exception-handling constructor

我有一个构造函数,它在同一个类中调用另一个构造函数。问题是我想捕获异常并将它们抛给调用第一个构造函数的方法。然而,Java不允许这样做,因为构造函数调用必须是构造函数中的第一个语句。

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();
    }
}

如果有人可以解释我怎么能做到这一点会很好。奖励将是知道为什么语言必须以这种方式表现,因为这总是很有趣。

1 个答案:

答案 0 :(得分:3)

你不需要构造函数中的那些try-catch块(事实上,你不能在那里写它,正如你已经想到的那样)。因此,将构造函数更改为:

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

实际上,构造函数中的catch块几乎没有做任何有效的工作。它只是重新创建了同一个异常的实例,然后抛出它。实际上并不需要这样做,因为如果抛出异常,它将自动传播到调用者代码,您可以在其中处理异常。

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

话虽如此,从构造函数中抛出一个已检查的异常并不是一个好主意,更糟糕的是在调用者代码中处理它们。
如果抛出异常,则在调用方法中处理它。那么你只是忽略了你的实例没有完全初始化的事实。继续执行该实例将导致一些意外行为。所以,你应该真的避免它。