看到一个程序讲final与static final的区别,
class SelfCounter{
          private static int counter;
          private int id = counter ++;
          
          public String toString(){
                    return "SelfCounter :" + id;
          }
}class WithFinalFields{
          static final SelfCounter wffs = new SelfCounter();
          final SelfCounter wff = new SelfCounter();
          
          
          public String toString(){
                    return "wff = " + wff + "\n wffs = " + wffs;
          }
}public class E18_StaticFinal {
          public static void main(String[] args) {
                    System.out.println("First Object :");
                    System.out.println(new WithFinalFields());
                    System.out.println("Second Object: ");
                    System.out.println(new WithFinalFields());
          }
}
,运行结果是
First Object :
wff = SelfCounter :1
 wffs = SelfCounter :0
Second Object: 
wff = SelfCounter :2
 wffs = SelfCounter :0 ,不太明白为什么两次wffs=SelfCounter:0,
我感觉counter被初始化为0后,id会自增为1,为什么声明为static final的对象后,id就是0?望高人指点

解决方案 »

  1.   

    static final SelfCounter wffs = new SelfCounter();
    wffs这个字段可以理解为单例,就是只存在唯一一个,不管你new多少对象,这个字段都是唯一的,而且不会变的
      

  2.   

    static final SelfCounter wffs = new SelfCounter();
    这个不管你建多少对象都是公用的一个 wffs
      

  3.   

    static的常量在类加载的时候被初始化,而实例常量在实例化的时候被初始化。其实上面的过程很简单。第一次实例化WithFinalFields的时候,虚拟机发现该类没有被加载,于是先加载类,加载类的同时需要初始化类的所有static无论是变量、常量还是块,于是wffs需要实例化一个SelfCounter对象,这个时候虚拟机发现SelfCounter类也没有被加载,于是加载SelfCounter类,同时初始化static变量counter为0,加载SelfCounter类完毕,开始实例化SelfCounter对象,初始化id为0(此时counter为0),同时counter变为1,这时SelfCounter对象的实例化完毕,并被赋值给WithFinalFields类的wffs常量,加载WithFinalFields类的过程完毕,开始正式实例化WithFinalFields对象,初始化wff常量,又需要实例化一个SelfCounter对象,这时虚拟机发现SelfCounter类已经被加载,于直接开始实例化SelfCounter对象,初始化id为1(此时counter为1),同时counter变为2,实例化WithFinalFields对象完毕,此时wffs的id为0,wff的id为1。第二次实例化WithFinalFields的时候,虚拟机发现该类已经被加载,直接实例化,不会初始化static无论是变量、常量还是块,于是直接初始化wff常量,需要实例化SelfCounter对象,该类也已经被加载,于是也直接实例化,初始化id为2(此时counter为2),同时counter变为3,实例化SelfCounter对象完毕,同时实例化WithFinalFields对象完毕,此时wffs的id仍然为0,wff的id为2。重点是静态的东西只会被初始化一次,发生在类加载的时候。
      

  4.   

    static的常量在类加载的时候被初始化,而实例常量在实例化的时候被初始化。
      

  5.   

    不太明白,那么fianl不也是不可变的吗
    final SelfCounter wff = new SelfCounter();
      

  6.   

    static final SelfCounter wffs = new SelfCounter();
    只在你第一次调用该类的时候被实例化, 它是一个类变量, 而非实例变量。 所以以后不管你new了多少对象,它们都用同一个类变量。
      

  7.   

    final 就是第一次初始化后不能改变的变量。 再加个 static ,就是一开始就初始化好的静态变量。用类名访问。。
      

  8.   


    final是不可变,但问题是有两个WithFinalFields对象,每个WithFinalFields对象都有它自己的wff常量,而且对于引用类型的常量,所谓不可变仅仅是引用不能重新指向其他对象,而不是对象内部的各种属性的值不可变。