标签:
【内容简介】
本文将讨论Java中被static修饰符修饰的成员变量的加载方式。
【能力需求 】
至少已经完整的掌握了Java的语法基础,掌握了面向对象中类、对象、属性、方法的概念,了解构造方法,了解类的属性的默认值。
【正文】
先看代码,并预测运行结果
public class StaticDemo { /** 成员变量 */ public static StaticDemo demo = new StaticDemo(); /** 成员变量 */ public static int i1; /** 成员变量 */ public static int i2 = 0; /** 构造方法 */ public StaticDemo() { i1++; i2++; } public static void main(String[] args) { System.out.println(i1); System.out.println(i2); } }
OK,代码完成,答案是:i1的值为1,i2的值为0 (请用鼠标框选这里的蓝色位置查看答案)
可能存在的误解:
一眼看过去,貌似i1和i2的值是一样的,因为它们都是成员变量,int型的成员变量的默认值就是0,所以i1和i2的声明看起来是等效的,当然,在一般情况下,这样的理解并没有错,但是,实际运行情况却不同!
众所周知,用static修饰的成员将具有最优先加载的权利,优先于一切非static成员之前,当然也包括各种构造方法,所以,这样的成员在内存的堆(Heap)空间内是无法存放的,它们会被存储到专门的静态域。
static成员加载的顺序是:static成员会依次从上至下的加载,而且加载时,先加载全部static成员的数据类型,并赋以默认值,然后再回过头来运行每个static成员的赋值语句!
所以,上面的代码运行流程是:
说到底,其实i2是被赋值了2次的,起初默认值为0,第1次赋值出现在构造方法中,值被改变为1,第2次出现在第7行,值被改变为0。
测试:
可以尝试把第3行语句public static StaticDemo demo = new StaticDemo();移动到第7行public static i2 = 0;之后,再次运行,发现结果都是1,即可印证刚才的解释。
最后,附加一些废话:
由于static成员不是属于任何一个对象的,那么就不应该使用传统的对象名.属性名进行访问(这样的语法是允许的,但是完全不推荐,如果不想被人鄙视,就不要这样做),由于它们是在某一个类中声明的,所以访问它们的语法是类名.属性名,当然,调用被static修饰的方法也是使用一样的语法。
另外,static成员只有1个值,假设Demo类存在static修饰的成员变量int x = 10,然后Demo类被创建了2个对象分别是demo1和demo2,其实Demo.x、demo1.x、demo2.x都是访问到的相同的变量,不管由哪种语法尝试改变它的值,始终都是改的同一个,如果要打印出来,将显示最后一次被修改的值。
【小结】
static成员会依次从上至下的加载,而且加载时,先加载全部static成员的数据类型,并赋以默认值,然后再回过头来运行每个static成员的赋值语句
如果本文有不足或者错误的地方,欢迎随时指出,如需转载,请注明出处,Thank you !
标签:
原文地址:http://www.cnblogs.com/soul-wing/p/5572659.html