Java字段初始化为抛出异常的函数

时间:2013-05-22 21:38:51

标签: java

我有一个问题,减少到考虑这个类:

class myClass
{
    static int s_int = getInteger();

    static int getInteger() throws myClassException
    {
        ...

这是我的问题:这不会编译,因为getInteger()抛出myClassException并且我在初始化s_int时没有尝试catch块。

当然,一个解决方案是构建一个getIntegerAndDealWithTheException(),它不会抛出异常并在初始化s_int时调用它。但我不愿意,因为那不是那么漂亮:我宁愿不用存根来乱丢代码。

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

非常感谢!

5 个答案:

答案 0 :(得分: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,这意味着你需要的不仅仅是一个简单的声明和表达式,所以静态初始化器在这里完成工作。

答案 1 :(得分:1)

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

在你的情况下:

class myClass
{
    static int s_int;

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

    static getInteger() throws myClassException
    {
        ...

答案 2 :(得分: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 {
   ...

Here您可以找到更详细的解释。

答案 3 :(得分: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(),而不是直接引用静态成员。

答案 4 :(得分:-1)

您应该考虑阅读Robert C. Martin所着的“清洁代码”一书中的“使用未经检查的例外”一章。在那之后,我认为你不会遇到这种问题。