在构造函数中的枚举和静态变量

28

编译器禁止在枚举构造函数中访问静态字段。下面的源代码有效,它使用了一个静态字段:

public enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count;

    TrickyEnum()
    {
        incrementCount();
    }

    private static void incrementCount()
    {
        count++;
    }

    public static void main(String... args)
    {
        System.out.println("Count: " + count);
    }
}

输出:

数量: 2.

但是尽管差异极小,下面的代码却无法正常工作:

public enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count;

    TrickyEnum()
    {
        count++; //compiler error
    }

    public static void main(String... args)
    {
        System.out.println("Count: " + count);
    }
}

在我的搜索中,人们通常声称问题是由于静态字段初始化的顺序。但第一个示例可以工作,所以为什么Java开发人员禁止第二个示例?它也应该可以工作。


你为什么要使用这个计数器? - Christophe Roussy
4
这只是一个例子,让我更好地了解Java。正确的方法是在静态块中递增静态计数器或不创建它。这是多余的,枚举元素可以计数,但我想了解这段代码中发生了什么。 - Pawel
这确实是一个有趣的案例。 - Christophe Roussy
1个回答

23
编译器允许调用静态函数,因为它不够智能化以禁止它:只有查看 incrementCount 方法的主体才能推断出调用的合法性。
当您运行以下代码时,这种禁止的原因将变得清晰:
enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count = 123; // Added an initial value

    TrickyEnum()
    {
        incrementCount();
    }

    private static void incrementCount()
    {
        count++;
        System.out.println("Count: " + count);
    }

    public static void showCount()
    {
        System.out.println("Count: " + count);
    }
}

public static void main (String[] args) throws java.lang.Exception
{
    TrickyEnum te = TrickyEnum.TrickyEnum1;
    TrickyEnum.showCount();
}

这会打印出来

1
2
123

对于阅读你的代码的程序员来说,这非常令人困惑:实际上,在静态字段初始化之前,incrementCount就已经进行了修改。

这里是在ideone上展示此代码的演示


3
我知道了。我想确认一下 :). 谢谢。 - Pawel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接