《Java编程思想》读书笔记——构造器初始化顺序
Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于局部变量,Java以编译时错误的形式来贯彻这种保证。
public static void main(String[] args) {int i;System.out.println(i++);
}运行结果:
Error:(12, 28) java: 可能尚未初始化变量i
类的没有基本数据成员保证都会有一个初始值,即使数据成员并未显示赋初值。对于类中的对象引用来说,如果不将其初始化,此引用就会获得一个特殊值null。
public class Dog {public String name;public int age;public Dog son;
}public class Test {public static void main(String[] args) {Dog dog = new Dog();System.out.println(dog.name);System.out.println(++dog.age);System.out.println(dog.son);}
}运行结果:
null
1
null
如果我们在定义类成员变量时没有为其定义初值,那么编译器就会自动为其加上初值。boolean
为false
,short
、int
、long
为0
,float
、double
为0.0
,char
为0
所以显示为空。
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
public class Window {public Window(){System.out.println("Window()");}
}public class House {public Window win = new Window();public House(){System.out.println("House()");}
}
public class Test {public static void main(String[] args) {House h = new House();}
}运行结果:
Window()
House()
从上例中可以看到,成员变量初始化先于构造方法运行。那么,对于静态成员来说,情况是否一样呢?来看看下面例子。
public class Bowl {Bowl(int marker){System.out.println("Bowl(" + marker + ")");}void f1(int marker){System.out.println("f1(" + marker + ")");}
}public class Table {static Bowl bowl1 = new Bowl(1);Table(){System.out.println("Table()");bowl2.f1(1);}void f2(int marker){System.out.println("f2(" + marker + ")");}static Bowl bowl2 = new Bowl(2);
}public class Cupboard {Bowl bowl3 = new Bowl(3);static Bowl bowl4 = new Bowl(4);Cupboard(){System.out.println("Cupboard()");bowl4.f1(2);}void f3(int marker){System.out.println("f3(" + marker + ")");}static Bowl bowl5 = new Bowl(5);
}public class Test {public static void main(String[] args) {System.out.println("Creating new Cupboard() in main");new Cupboard();System.out.println("Creating new Cupboard() in main");new Cupboard();table.f2(1);cupboard.f3(1);}static Table table = new Table();static Cupboard cupboard = new Cupboard();
}运行结果:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
初始化顺序是先初始化静态对象(如果它们因前面的对象创建过程而被初始化),而后是非静态对象
如果大家知道这一点,上面输出结果就不难解释了——Test
类中,先初始化table
,进入table
类中先有静态属性bowl1
,再进入Bowl
类中,发现没有成员变量,直接调用Bowl
的构造方法,输出Bowl(1)
。再回到Table
类中,再有静态属性bowl2
,同理输出Bowl(2)
。然后调用Table
类的构造方法,输出Table()
、f1(1)
,此时Test
类中的静态属性table
初始化完成,再根据相同的原则初始化cupboard
。**不过这里值得注意的是,静态属性只会初始化一次。**最后执行main()
方法里的内容。
最后,我们来总结一下对象的创建过程,假设有个名为Dog的类:
- 即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog地对象时,或者Dog类地静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
- 然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
- 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
- 这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值,而引用则被设置成了null。
5、执行所有出现于字段定义处的初始化动作。
6、执行构造器。
《Java编程思想》读书笔记——构造器初始化顺序相关推荐
- JAVA编程思想读书笔记(三)--RTTI
接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...
- Java编程思想读书笔记(七)
点击蓝字 关注我们 今天是端午节,在这里祝大家端午节安康.过节的同时也不要忘记知识储备,今天我 为大家带来了Java编程思想第七节多形性读书笔记.请大家一起品鉴,如果发现里面有啥写的不对的地方,请大家 ...
- Java编程思想读书笔记一:并发
1. Thread.yield( )方法 当调用yield()时,即在建议具有相同优先级的其他线程可以运行了,但是注意的是,仅仅是建议,没有任何机制保证你这个建议会被采纳 .一般情况下,对于任何重要的 ...
- Java编程思想读书笔记——初始化与清理(二)
5.6 成员初始化 1)类的每一个基本数据类型成员,如果不显式赋予初值,都会有一个初始值: 2)对于引用类型成员,如果不显式赋予初值,则其初始值为null. 3)也可以直接在类中,对成员变量直接赋予初 ...
- java编程思想读书笔记
多态 任何域的访问操作都将有编译器解析,如果某个方法是静态的,它的行为就不具有多态性 java默认对象的销毁顺序与初始化顺序相反 编写构造器时有一条有效的准则:"尽可能用简单的方法使对象进入 ...
- Java编程思想读书笔记——复用类
第七章 复用类 组合和继承是复用类的两种主要方式. 7.1 组合语法 组合只需将对象引用置于新类中即可.这些引用的初始化方式有四种: 1) 在定义对象的地方进行初始化,即在创建新类对象前就被初始化: ...
- Java编程思想读书笔记——多态
第八章 多态 多态(动态绑定.后期绑定或运行时绑定)分离做什么和怎么做,从另外一个角度讲接口和实现分离. 8.1 再论向上转型 将一个对象的引用同时看作其父类的引用的做法称为向上转型. 8.1.1 忘 ...
- Java编程思想读书笔记(02)
第十三章字符串 字符串是不可变的:是final类固不能继承它:也不能通过指向它的引用来修改它的内容. StringBuilder是Java SE5引用的,在这之前用的是StringBuffer.后者是 ...
- JAVA编程思想——读书笔记 类再生
文章目录 类再生 1. 组合的语法 对象句柄的初始化 2. 继承的语法 3. 初始化父类 默认构造器 有参构造器 4.合成和继承的结合 5.选择组合还是继承 谨慎使用继承 6.向上转型 7.什么是向上 ...
最新文章
- Waymo无人卡车高调重返凤凰城,但货运先机已失
- 学长毕业日记 :本科毕业论文写成博士论文的神操作20170402
- highcharts如何把图多余的空白页面_零基础如何快速学会WORD基础操作?有秘籍了.........
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- react学习(18)----vs 全局搜索
- matlab 多项式表达,MATLAB自学笔记(十七):多项式及其函数
- 【晒出你的第83行代码】剑指星辰,两位开发者贴出了小试牛刀的毕设代码
- 海龟绘图小动物_被解救海龟经野化训练后放归大海,这一幕让人惊叹不已
- 静态long类型常量serialVersionUID的作用
- 《复联4》首轮公映票房27.5亿美金 超《阿凡达》创纪录
- 分享一个漂亮WPF界面框架创作过程及其源码
- 步步为营103-ZTree 二级联动
- 计算机网络相关知识(http状态码 首部字段)
- 行政区划信息抽取算法(区划抽取)
- 耳机及音响--煲机软件
- USB转串口设备如何固定串口号
- git send-email 使用126邮件发送patch
- VSPD及友善串口调试助手下载地址
- lightoj1278
- 上海矽昌通信技术有限公司自研路由芯片
热门文章
- 页面响应慢查服务器原因,网站加载速度慢?3步排查找原因
- linux redhat配置网卡,Linux_RedHat服务器网卡阵列配置攻略,网卡阵列配置1.修改vi /etc/rc.d/r - phpStudy...
- CISCO ASA5505 如何清空配置
- jira在哪创建子任务?
- NLP模型检查英语语法错误
- 《玩转Spring全家桶》第70-77节
- cms 和 g1的主要区别
- IMX7的双核通信例子问题(rpmsg)
- 序列处理的深度学习框架——从RNN到Transformer
- Bean依赖注入的3种数据类型