【问题标题】:Why couldn't I access the static field in enum in constructor? [duplicate]为什么我不能在构造函数中访问枚举中的静态字段? [复制]
【发布时间】:2012-12-14 04:51:43
【问题描述】:

可能重复:
Cannot access static field within enum initialiser

我的情况:

enum Attribute { POSITIVE, NEGATIVE }
enum Content {
    C1(Attribute.POSITIVE),
    C2(Attribute.POSITIVE),
    ... // some other positive enum instances.
    Cm(Attribute.NEGATIVE),
    ... // some other negative enum instances.
    Cn(Attribute.NEGATIVE);

    private final Atrribute a;
    static int negativeOffset = 0;
    private Content(Atrribute a) {
        this.a = a;
        if ( a.compareTo(Attribute.POSITIVE) == 0 ) {
               negativeOffset ++;
        }
    }

    public static int getNegativeOffset() { return negativeOffset; }
} 

我的意图是每当我添加一个新的枚举(带有 POSITIVE 属性)时,将negativeOffset 加一,然后我可以调用 getNegativeOffset() 来获取负数的起点 枚举并做任何我想做的事情。

但是comlier抱怨说

Cannot refer to the static enum field Content.negativeOffset within an initializer

【问题讨论】:

标签: java


【解决方案1】:

你可以使用这个“技巧”:

private static class IntHolder {
    static int negativeOffset;
}

然后像这样引用变量:

IntHolder.negativeOffset ++;

return IntHolder.negativeOffset; 

这样做的原因是 JVM 保证在初始化 IntHolder 静态内部类时初始化变量,直到它被访问时才会发生。

整个类将如下,编译:

enum Attribute { POSITIVE, NEGATIVE }
enum Content {
    C1(Attribute.POSITIVE),
    C2(Attribute.POSITIVE),
    ... // some other positive enum instances.
    Cm(Attribute.NEGATIVE),
    ... // some other negative enum instances.
    Cn(Attribute.NEGATIVE);

    private final Attribute a;

    private static class IntHolder {
        static int negativeOffset;
    }

    private Content(Attribute a) {
        this.a = a;
        if ( a == Attribute.POSITIVE) {
               IntHolder.negativeOffset ++;
        }
    }

    public static int getNegativeOffset() { return IntHolder.negativeOffset; }
}

注意拼写错误的更正以及使用== 而不是compareTo()Attribute 枚举值的更简单比较

【讨论】:

  • 谢谢,好技巧!我没想到这个线程安全技巧在这里也有效!顺便说一句,我仍然想知道为什么原来的方法行不通。静态fileld初始化不是在构造函数之前发生的吗?
  • 您的问题是枚举在实例之前不能有任何声明,这意味着您无法初始化(或使用)实例的构造函数所需的任何静态字段。然而,通过将字段放在 another 类中,尽管是一个内部静态类,另一个类在第一次使用时被加载(并静态初始化),这是在构造函数中。这种模式是一种非常棒的方式,可以线程安全地延迟初始化单例而无需任何同步。
猜你喜欢
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
相关资源
最近更新 更多