【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。
- 【OCJP】 第3题---类变量的初始化
- 【OCJP】 第2题---Set中subSet()方法的运用
- OCJP之有继承关系时,对象的初始化顺序
- 【OCJP】 第1题---允许使用泛型类,避免一个不用检查的警告
- OCJP第5天
- Java类的初始化、变量的初始化
- 变量的初始化、类的初始化
- 【OCJP】 第4题---Comparable只有个compareTo()方法
- 类变量、实例变量的初始化顺序
- 类的成员变量初始化
- 类的成员变量初始化
- 类变量的初始化时机
- Java类变量的初始化
- 类中变量的初始化
- 类变量的初始化时机
- 类成员变量的初始化
- ocjp认证的作用
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造方法)
- tomcatec出错-Web app root system property already set to different value
- 晶格振动
- [LeetCode-82] Remove Duplicates from Sorted List II
- 高并发memecache 学习视频
- Java 读取properties配置文件
- 【OCJP】 第3题---类变量的初始化
- Google Guava Collections 使用介绍
- Ubuntu 安装磁盘分区及启动项添加
- AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL资源
- HVM,Hexagon处理器的虚拟器解决方案
- 优秀程序员的18大法则 -- The Principles of Good Programming
- IOS 获得当前系统时间(当前时区)
- Android中的异常
- linux下tomcat升级