static成员加载时机

来源:互联网 发布:中国阜宁网络发言人 编辑:程序博客网 时间:2024/05/01 01:34
废话不多说 看看这段代码。告诉我结果:

[java] view plain copy
  1. import java.io.*;  
  2. class Test    
  3. {  
  4.       
  5.     public static Test t = new Test();  
  6.       
  7.     public  Test(){  
  8.         a++;  
  9.         b++;  
  10.     }  
  11.       
  12.     public static int a;  
  13.     public static int b = 0;  
  14.       
  15.     public static void main (String[] args) throws java.lang.Exception  
  16.     {  
  17.           
  18.         System.out.println(t.a + " " + t.b);  
  19.     }  
  20. }  


如果你毫无疑问的答很简单 static 是类所有的,每个实例改变都会变他的值,答案是 1,1   那么。。恭喜你上套了。


你可以亲自试一下结果。 是1,0  这是为什么呢。  原来一个类加载的时候会经历以下步骤:


加载:查找并加载类的二进制数据

连接 
     -验证:确保被加载的类的正确性    //为什么会检验? 因为.class有可能是手动改的
     -准备:为类的静态变量分配内存,并将其初始值转化为默认值 
     -解析:把类中的符号引用转换为直接引用
初始化:为类的静态变量赋予正确的初始值

回过头再来看最上面的一段程序。发现实例是在static成员上面写的,也就是在赋值之前。
那么在准备阶段, 会为静态变量分配内存,初始值为默认值,这时候 a 和b 都是 0,0   然后创建实例  a++;b++; 此时 a 和b的值都是1;

重点来了。接下来到了初始化过程, 会为静态变量赋予正确的初始值, 由于a没有赋值,所以还为1没有变化,但是b被赋予正确的初始值0。
所以这下真相大白了。 b的真实变化过程是 0-->1-->0。

附上一些笔记:

类的主动使用
     1.创建类的实例
     2.访问静态变量
     3.调用静态方法
     4.反射
     5.初始化一个类的子类
     6.虚拟机启动时候被标明启动类的类


将二进制读入到内存中  放在运行时的方法去内   堆內创建一个Class对象,用来封装类在方法区内的数据结构


加载class的方式
1.从本地系统直接加载
2.网络加载
3.zip  jar包加载
4.从专有数据库提取.class
5,将java 源文件动态编译为.class


0 0
原创粉丝点击