直接上代码,大家看过执行结果,会不会觉得有问题呢?
public class Price {
//类成员是Price实例
final static Price INSTANCE=new Price(5.0);
//再定义一个类变量
static double initPrice=20;
//定义实例变量
double currentPrice;
public Price(double discount) {
//根据类变量计算实例变量
currentPrice=initPrice-discount;
}
public static void main(String[] args) {
//通过Price的INSTANCE实例来访问currentPrice变量
System.out.println(Price.INSTANCE.currentPrice);
//显式创建Price实例
Price p=new Price(5.0);
System.out.println(p.currentPrice);
}
}
执行结果:
----------------------------------
-5.0
15.0
----------------------------------
第一次我觉得这个程序的结果应该都是15.0;但结果却出人意料,那么为什么不是这样呢?
看代码真的不容易看出来,若要从内存分配的角度来一步步分析就迎刃而解了。
直接上图:
原因总结:
第一次用到Price类时,程序开始对Price类初始化,注意是对“类”初始化,这时只在main栈区处理,如图1;而初始化分为以下两步:
(1)系统为Price两个类变量分配内存空间
(2)按初始化代码(定义时指定初始值和初始化块中执行初始值)在源代码中的排列顺序对类变量执行初始化
接着程序按顺序依次给INSTANCE和initPrice变量赋值,对INSTANCE赋值时要调用Price(5.0),创建Price实例,并给currentPrice赋值,而此时的initPrice变量的值为0.0,
所以最终得到的currentPrice的值为-5.0(图2);然后系统再给initPrice赋值20.0(图3),这时对INSTANCE类对象已经没有影响了。
看到这里大家是否明白了呢?那就不啰嗦下去了...
这里需要说明一点的是:静态变量(static修饰的变量)又叫类变量,虽然该类的对象也能够访问它们、修改它们(这点java做的不太符合逻辑),但它们只属于类本身,标准的访问方式为:类名.静态变量;