1

我有一个问题可以归结为考虑这个类:

class myClass
{
    static int s_int = getInteger();

    static int getInteger() throws myClassException
    {
        ...

这是我的问题:这不会编译,因为getInteger()throwsmyClassException并且在初始化时我没有 try catch 块s_int

当然,一种解决方案是构建一个getIntegerAndDealWithTheException()不会引发异常并在初始化 s_int 时调用它。但我宁愿不这样做,因为那不那么漂亮:我宁愿不要在代码中乱扔存根。

我在初始化 s_int 时错过了一个语法技巧吗?

非常感谢!

4

5 回答 5

2

您可以使用静态初始化程序。静态初始化器是介于两者之间的代码块,static {用于}初始化static比简单声明和表达式占用更多代码的变量。

class myClass
{
    static int s_int;

    static
    {
       try {
          s_int = getInteger();
       } catch (myClassException e) {
          // Handle it here.
       }
    }

    static getInteger() throws myClassException
    {
        ...

根据JLS 11.2.3 ,静态初始化程序可能不会抛出已检查的异常。去引用:

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

所以你必须抓住Exception,这意味着你需要的不仅仅是一个简单的声明和表达式,所以静态初始化器在这里完成了这项工作。

于 2013-05-22T21:41:03.010 回答
1

static您可以在类块内初始化静态属性。

在你的情况下:

class myClass
{
    static int s_int;

    static {
        try {
            s_int = getInteger();
        } catch (myClassException e) {
            // exception handling code
        }
    }

    static getInteger() throws myClassException
    {
        ...
于 2013-05-22T21:40:42.147 回答
1

我将详细说明当您捕获异常时该怎么做。

类初始化应该放在静态初始化器中。正如您的编译器警告的那样,您不能在静态初始化程序中留下未捕获的异常。你必须抓住它并用它做点什么。如果您无法从异常中恢复,则您的类未初始化。然后你必须抛出一个ExceptionInInitializerError表明这个类状态无效的信号。

class MyClass {
    static int s_int;

static {
    try {
        s_int = getInteger();
    catch (MyClassException e) {
        throw new ExceptionInInitializerError(e);
        // or if it is ok, s_it = some_default_value; 
    }

static int getInteger() throws MyClassException {
   ...

在这里你可以找到更详细的解释。

于 2013-05-22T21:52:09.487 回答
0

您可以(但可能不应该)使用static块:

class myClass {

    static int s_int;
    static {
        try {
           s_int = getInteger();
        }
        catch(Exception e) {
            // ...
        }
    }

}

另一种方法是延迟加载值。

class myClass {

    static Integer s_int = null;

    public static int getInteger() throws Exception {
        if(s_int == null) {
            s_int = /* ? */
        }
        return s_int;
    }

    public static void wtv() {
        // never refer to the static member - use the method,
        // which will lazy-load the value
        int s_int = getInteger();
    }

    public static void doSomething() {
        // never refer to the static member - use the method,
        // which will lazy-load the value
        int s_int = getInteger();
    }

}

...然后总是指代getInteger(),从不直接指代静态成员。

于 2013-05-22T21:43:39.193 回答
-1

您应该考虑阅读 Robert C. Martin 的“Clean Code”一书的“Use unchecked expetions”一章。在那之后,我认为您不会遇到这种问题。

于 2013-05-22T21:48:39.427 回答