【OCJP】 第3题---类变量的初始化

来源:互联网 发布:刘慈欣光荣与梦想知乎 编辑:程序博客网 时间:2024/05/20 00:35

最近在一本书上看到一个题目,第一眼看起来没什么特别的,很容易看完,就得出了自己的答案,然而做错了,题目是这样的:


本题中main()方法,就是比较类实例的变量INSTANCE.currentPrice和对象的变量p.currentPrice之间的不同。

class Price{//类成员是Price实例final static Price INSTANCE = new Price(2.8);//再定义一个类变量static double initPrice = 20;//定义该Price的currentPrice实例变量double currentPrice;public Price(double discount){//根据静态变量计算实例变量currentPrice = initPrice - discount;}}public class Main{public static void main(String[] args) {//通过Price的INSTANCE访问currentPrice实例变量System.out.println(Price.INSTANCE.currentPrice);//显式创建Price实例Price p = new Price(2.8);//通过显式创建的Price实例访问currentPrice实例变量System.out.println(p.currentPrice);}}


我最开始以为答案是两个17.2,其实是-2.8 和 17.2 。

看了题目解释才明白,抱着半信半疑的心态,又在eclipse中跑了一下,确实如此。

现在把我的理解给大家分享下。

只说为什么INSTANCE.currentPrice的结果是-2.8。

Price类中有两个类变量(INSTANCE 和 initPrice),系统首先给这两个类变量分配内存空间,此时这两个变量的值分别是 null 和 0.0 ,接着开始初始化,类变量初始化是顺序是按代码的先后顺序执行的,先执行这一句:

final static Price INSTANCE = new Price(2.8);


这句代码要用到Price的构造函数:

public Price(double discount){//根据静态变量计算实例变量currentPrice = initPrice - discount;}

执行构造函数时,initPrice的值还是0,还是0,还是0。重要的事情说三遍。而不是20,这个时候还没轮到下面这句代码:

static double initPrice = 20;

0 - 2.8 = -2.8,好了,currentPrice初始化完毕,按照代码顺序,现在开始对initPrice进行初始化,赋值为20,这时它对currentPrice已没有影响了(不过它对main()方法中p对象会有影响)。到此为止,两个类变量初始化完毕。


快完了,最后放个大招,嘿嘿。

class Main {static {System.out.println(Main.string + " " + Main.integer);}final static String string = "static";final static Integer integer = 1;public static void main(String[] args) {}}

很快答案就算出来了,

来对下答案,

恭喜你,

答错了。

正确答案是:static null

你的答案是:static 1吧,是的一开始我也是这么写的。先来看下下边的代码:

class Main {final static String string = "static";final static Integer integer = 1;static {System.out.println(Main.string + " " + Main.integer);}public static void main(String[] args) {}}

再做答一次,什么,你不敢说答案了,说吧,嗯,对,就是:stack 1。

这是为什么呢。

这里有解释:http://stackoverflow.com/questions/12448465/in-what-order-are-static-blocks-and-static-variables-in-a-class-executed

看不懂,用UC、360浏览器的翻译,还是看不懂。暂时理解为Integer i是个对象。

结合里边的答案,再写一个demo。



0 0