3

我有一个构造函数,它调用同一个类中的另一个构造函数。问题是我想捕获异常并将它们向前抛出到调用第一个构造函数的方法。然而 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();
    }
}

如果有人可以解释我如何做到这一点,那就太好了。一个好处是知道为什么语言必须以这种方式表现,因为这总是很有趣。

4

1 回答 1

4

您不需要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
    }
}

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

于 2013-09-22T18:00:15.840 回答