必须捕获或声明在静态初始化程序中抛出未报告的异常

时间:2017-01-13 14:45:57

标签: java

我有这段代码:

class C {
    private static final Object myObject = makeObject(); // *

    private static Object makeObject() throws IOException {
        try {
           ...
        } catch (IOException e) {
            ...
            throw e;
        }
    }
}

当我尝试编译它时,我会在标有*的行中出现异常:

error: unreported exception IOException; must be caught or declared to be thrown

如何声明在这种情况下抛出的异常?我知道我能抓住它,我的问题是关于语法。

1 个答案:

答案 0 :(得分:6)

如果你想保留makeObject()投掷IOException的签名,你必须这样做:

class C {
    private static final Object myObject;

    static {
        try {
            myObject = makeObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static Object makeObject() throws IOException {
        try {
           ...
        } catch (IOException e) {
            ...
            throw e;
        }
    }
}

不允许从初始化(静态)字段的方法或静态块中抛出已检查的异常。但是允许抛出未经检查的(运行时)异常。因此,您必须捕获IOException并将其包装在RuntimeException的(子类)中。

或者,您可以通过在那里进行包装来抛出IOException from makeObject()`:

class C {
    private static final Object myObject = makeObject(); // OK now

    private static Object makeObject() { // no 'throws'
        try {
           ...
        } catch (IOException e) {
            ...
            throw new RuntimeException(e); // wrap here
        }
    }
}

IOException是一个经过检查的异常,Java语言规范禁止将其(可能)抛出到类变量初始化器或静态初始化器中(参见JLS §11.2.3. Exception Checking):

  

如果命名类或接口的类变量初始化程序(第8.3.2节)或静态初始化程序(第8.7节)可以抛出已检查的异常类,则是编译时错误。

此限制不适用于未检查(运行时)异常。