为什么在静态块中的try-catch块中分配最终字段会被拒绝?

时间:2015-06-26 16:19:58

标签: java static initialization final

我正在尝试写下面的课程:

public class Secteur {
    private final static int num_secteur;
    static{
            try {
                num_secteur = SecteurDAO.getCurrNumSecteur();
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            }

    }
}  

但我有以下警告:

  

空白的最终字段num_secteur可能尚未初始化

SecteurDAO.getCurrNumSecteur()方法访问数据库以获取将设置为num_secteur字段的整数。
我的代码有什么问题?

2 个答案:

答案 0 :(得分:3)

SecteurDAO.getCurrNumSecteur()的调用可能会失败(抛出异常),因此没有值分配给num_secteur。因此,如果发生异常,它可能不会被初始化。

要解决这个问题,你可能想要用一些特殊值(例如-1)初始化它,或者在catch块中设置该值。

哦,并删除final关键字,否则您会收到错误消息“可能已经分配了最终字段num_secteur”。那是因为你只能为一个最终字段赋值一次,即使你知道在异常的情况下不能发生赋值(因为之前会抛出异常),编译器也无法确定这一点,因此告诉您变量可能已经分配。

答案 1 :(得分:2)

如上所述,如果存在异常,则可能不会在静态初始值设定项的末尾分配变量。

您可能会考虑在try块之前或catch块之后分配变量,但这可能会导致对变量进行2次分配,因此不允许这样做。

您可能会考虑为catch块中的变量分配无效值,但这仍然会导致对变量进行2次分配。

将此变量分配一次并保持num_secteur final的最佳方法是使用临时变量并将其分配到num_secteur块中的finally

private final static int num_secteur;
static
{
    int test = -1;  // Invalid value.
    try {
        test = SecteurDAO.getCurrNumSecteur();
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // Only assigned here, exactly once.
        num_secteur = test;
    }
}