参考:http://hllvm.group.iteye.com/group/topic/37682

           http://blog.csdn.net/javakuroro/article/details/6817520

           http://blog.csdn.net/qq1623267754/article/details/36190715

=======================================================================

首先来说,普通的静态变量赋初始值是在<clinit>中,准备阶段为类变量分配内存,并赋默认值(boolean设置为false,int设为0,double设为0.0d等)。

而常量静态变量 (static final)在Class文件里对应的field_info里带有ConstantValue属性,里面记录了该字段的常量值(在常量池里的编号),在类的初始化阶段会对类里的带有

ConstantValue的final static变量做初始化(第6步),这在调用<clinit>()之前。

final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变。 static修饰的属性的初始化在编译期(类加载的时候),初始化后能改变。对于基本类型数据,final会

将值变为一个常数(创建后不能被修改);但是对于对象句柄(亦可称作引用或者指针),final会将句柄变为一个常数(进行声明时,必须将句柄初始化到一个具体的对象。而且不能

再将句柄指向另一个对象。但是,对象的本身是可以修改的。这一限制也适用于数组,数组也属于对象,数组本身也是可以修改的。方法参数中的final句柄,意味着在该方法内部,我

们不能改变参数句柄指向的实际东西,也就是说在方法内部不能给形参句柄再另外赋值)。

1.import java.util.Random;  
2.  
3.//这个例子想说明一下static final 与 final的区别  
4.public class StaticAndFinalTest {  
5.      
6.    private static Random rand = new Random(47); //47作为随机种子,为的就是产生随机数。  
7.      
8.    private final int a = rand.nextInt(20);  
9.      
10.    private static final int B = rand.nextInt(20);  
11.  
12.    public static void main(String[] args) {  
13.        StaticAndFinalTest sf = new StaticAndFinalTest();  
14.        System.out.println("sf : " + "a=" + sf.a);  
15.        System.out.println("sf : " + "B=" + sf.B);  
16.        System.out.println("------------------------------");  
17.        StaticAndFinalTest sf1 = new StaticAndFinalTest();  
18.        System.out.println("sf1 : " + "a=" + sf1.a);  
19.        System.out.println("sf1 : " + "B=" + sf1.B);  
20.    }  
21.  
22.}  

运行结果:

  • sf : a=15 
  • sf : B=18 
  • -------------- 
  • sf1 : a=13 
  • sf1 : B=18 

    可以看到,在sf和sf1对象中,a的值不是唯一的,但B的值是不会通过创建sf1对象而改变。这是因为它是static,在装载时已被初始化,而不是每次创建新对象时都初始化。

posted on 2017-11-05 08:50  blythe  阅读(678)  评论(0编辑  收藏  举报