5

我发现它与枚举很相似。这是 Kathy Siera 书中的一个例子:

    public class WeatherTest {

    static Weather w;

    public static void main(String[] args) {
        System.out.print(w.RAINY.count + " " + w.Sunny.count + " ");
    }
}

enum Weather {

    RAINY, Sunny;
    int count = 0;

    Weather() {
        System.out.print("c ");
        count++;
    }
}

输出为 cc 1 1。明白了。现在我想如果计数字段是静态的怎么办?输出会是 cc 2 2 吗?在此基础上,我将count变量修改为static。但后来我看到的是:编译时错误:从初始化程序非法引用静态字段。

在网上搜索我发现这是 Sun 的某种漏洞,它允许使用可以更改静态字段的静态方法。好的..所以现在我使用静态方法 incr 来完成我的工作:

     class WeatherTest {

    static Weather w;

    public static void main(String[] args) {
        System.out.print(w.RAINY.count + " " + w.Sunny.count + " ");
    }
}

enum Weather {

    RAINY, Sunny;

    Weather() {
        System.out.print("c ");
        incr();
    }
    static int count = 0;

    static void incr() {
        count++;
    }
}

令我惊讶的是,我得到了输出:cc 0 0!在我开枪之前,谁能向我解释一下这种行为?

4

1 回答 1

6

枚举值可以被认为是美化的静态字段(它们在幕后)。

所以,如果你Weather是一个普通的 Java 类,它会是这样的:

 class Weather {
   public final static Weather RAINY = new Weather( );
   public final static Weather Sunny = new Weather( );

   static int count = 0;

   Weather( ) {
     System.out.print("c ");
     incr();
   }

   static void incr()
   {
      count++;
   }
 }

您可以看到它是在两个枚举值之后count声明的,这意味着它也在创建两个值之后被初始化。此外,遇到未初始化的静态变量的每个函数调用都将其视为使用默认值初始化( for it's )。int0

incr因为您在正确初始化后从不调用count,所以您看到它的值仍然0

于 2012-07-20T16:37:17.930 回答