java对象的初始化顺序(详细解释)
文章目录
前言
小伙伴们好,今天我们来分析一下java对象的初始化顺序。下面的内容是我自己悟了很长时间悟出来的。我的几个舍友看了这篇文章后说感觉对他们帮助很大,希望也能给大家带来帮助。对象初始化顺序很多小伙伴们容易迷惑的一个点,也是大学期末考试一个很重要的考点。下面我通过几道例题,教大家如何分析。分析过程中文字有点多,请大家耐心看,边看边思考并去看题目的代码。好了,废话不多说了,我们开始吧。
一、需要记住的几个原则
- static结构随着类的加载而加载,并且在一个类中只加载一次。
- 调用构造器时,一定要先解决成员变量问题。等把成员变量全部初始化完毕后,再去调用该类的构造器。
- 调用子类构造器时,一定要注意,如果子类没有显式调用父类构造器,那么默认是super(),调用父类构造器。所以,调用子类构造器时,会先去加载父类的结构。
二、无继承关系
1.题目
package ch6;
public class Computer { //电脑
private MainBoard mb=new MainBoard(); //主板,域成员变量
private HardDisk hd=new HardDisk(""); //硬盘,域成员变量
static{
System.out.println("Computer类的静态代码块输出的语句,下面开始定义静态成员变量"); //静态代码段
}
private static Cpu cpu=new Cpu("Intel"); //CPU,静态成员变量
public Computer(){ //默认(无参)构造方法
System.out.println("我是一台电脑,我刚被创建(制造)出来,我是用无参数的构造方法创建的");
}
public Computer(MainBoard mb,HardDisk hd,Cpu cpu) { //带参构造方法
this.hd = hd;this.mb = mb;this.cpu = cpu;
System.out.println("我是一台电脑,我刚被创建(制造)出来,我是用有参数的构造方法创建的");
}
public static void main(String args[]){
System.out.println("main方法:下面开始创建(制造)第一台电脑,我只需要Cpu是Intel的,别的不在乎,所以用无参数的构造方法创建");
Computer computer1=new Computer();
System.out.println("\n\nmain方法:下面开始创建(制造)第二台电脑,我很关注主板、硬盘、Cpu的品牌,所以用有参数的构造方法创建");
System.out.println("main方法:先创建三个成员对象");
MainBoard mb=new MainBoard("联想");
HardDisk hd=new HardDisk("西数");
Cpu cpu=new Cpu("Intel");
System.out.println("main方法:然后调用Computer的有参数构造方法创建电脑对象");
Computer computer2=new Computer(mb,hd,cpu);
}
}
class HardDisk{
String type;
public HardDisk(){ //无参构造方法
type="没有品牌";
System.out.println("我是一个硬盘,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是"+type);
}
public HardDisk(String type){ //有参构造方法
this.type=type;
System.out.println("我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是"+type);
}
}
class MainBoard{
String type;
public MainBoard(){
type="没有品牌";
System.out.println("我是一块主板,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是"+type);
}
public MainBoard(String type){
this.type=type;
System.out.println("我是一块主板,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是"+type);
}
}
class Cpu{
String type;
public Cpu(){
type="没有品牌";
System.out.println("我是一个CPU,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是"+type);
}
public Cpu(String type){
this.type=type;
System.out.println("我是一个CPU,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是"+type);
}
}
2.运行结果
/*
Computer类的静态代码块输出的语句,下面开始定义静态成员变量
我是一个CPU,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是Intel
main方法:下面开始创建(制造)第一台电脑,我只需要Cpu是Intel的,别的不在乎,所以用无参数的构造方法创建
我是一块主板,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是没有品牌
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是
我是一台电脑,我刚被创建(制造)出来,我是用无参数的构造方法创建的
main方法:下面开始创建(制造)第二台电脑,我很关注主板、硬盘、Cpu的品牌,所以用有参数的构造方法创建
main方法:先创建三个成员对象
我是一块主板,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是联想
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是西数
我是一个CPU,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是Intel
main方法:然后调用Computer的有参数构造方法创建电脑对象
我是一块主板,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是没有品牌
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是
我是一台电脑,我刚被创建(制造)出来,我是用有参数的构造方法创建的
*/
3.分析
三、有继承关系
1.题目 ①
注意一下,这个题的代码与无继承关系里那道题代码有联系
package ch6;
public class NoteComputer extends Computer {
static{
System.out.println("NoteComputer类的静态代码块输出的语句,下面开始定义静态成员变量");
}
private static Displayer displayer=new Displayer();
public NoteComputer() {
System.out.println("我是一台笔记本电脑,我刚被创建(制造)出来,我是用无参数的构造方法创建的");
}
public NoteComputer(MainBoard mb,HardDisk hd,Cpu cpu,Displayer displayer) {
super(mb,hd,cpu);
this.displayer = displayer;
System.out.println("我是一台笔记本电脑,我刚被创建(制造)出来,我是用有参数的构造方法创建的");
}
public static void main(String[] args) {
System.out.println("main方法:下面开始创建(制造)第一台笔记本电脑,我只需要Cpu是Intel的,别的不在乎,所以 要用无参数的构造方法创建");
NoteComputer computer1=new NoteComputer();
System.out.println("\n\nmain方法:下面开始创建(制造)第二台笔记本电脑,我很关注主板、硬盘、Cpu、显示器的品牌,所以要用有参数的构造方法创建");
System.out.println("main方法:先创建四个成员对象");
MainBoard mb=new MainBoard("联想");
HardDisk hd=new HardDisk("西数");
Cpu cpu=new Cpu("Intel");
Displayer displayer=new Displayer("IBM");
System.out.println("main方法:然后要调用NoteComputer的有参数构造方法创建笔记本电脑对象");
NoteComputer computer2=new NoteComputer(mb,hd,cpu,displayer);
}
}
class Displayer{
String type;
public Displayer(){
type="没有品牌";
System.out.println("我是一块笔记本专用显示器,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是"+type);
}
public Displayer(String type){
this.type=type;
System.out.println("我是一块笔记本专用显示器,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是"+type);
}
}
2.运行结果 ①
/*
Computer类的静态代码块输出的语句,下面开始定义静态成员变量
我是一个CPU,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是Intel
NoteComputer类的静态代码块输出的语句,下面开始定义静态成员变量
我是一块笔记本专用显示器,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是没有品牌
main方法:下面开始创建(制造)第一台笔记本电脑,我只需要Cpu是Intel的,别的不在乎,所以 要用无参数的构造方法创建
我是一块主板,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是没有品牌
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是
我是一台电脑,我刚被创建(制造)出来,我是用无参数的构造方法创建的
我是一台笔记本电脑,我刚被创建(制造)出来,我是用无参数的构造方法创建的
main方法:下面开始创建(制造)第二台笔记本电脑,我很关注主板、硬盘、Cpu、显示器的品牌,所以要用有参数的构造方法创建
main方法:先创建四个成员对象"
我是一块主板,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是联想
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是西数
我是一个CPU,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是Intel
我是一块笔记本专用显示器,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是IBM
main方法:然后要调用NoteComputer的有参数构造方法创建笔记本电脑对象
我是一块主板,我刚被创建(制造)出来,我是用无参数的构造方法创建的,我的型号是没有品牌
我是一个硬盘,我刚被创建(制造)出来,我是用有参数的构造方法创建的,我的型号是
我是一台电脑,我刚被创建(制造)出来,我是用有参数的构造方法创建的
我是一台笔记本电脑,我刚被创建(制造)出来,我是用有参数的构造方法创建的
*/
3.分析 ①
4.题目 ②
package teach_exer;
/**
* @author panshouguan
* @create 2021-04-23 18:23
*/
class TestClass {
static {
System.out.println("TestClass Static");
}
public TestClass(String name) {
System.out.println("TestClass " + name + " init");
}
void test() {
System.out.println("makeInner() invoked");
}
}
class ObjectCreation {
TestClass testClass = new TestClass("fieldValue1");
static TestClass testClass2 = new TestClass("staticValue1");
static {
testClass2.test();
}
public ObjectCreation() {
System.out.println("ObjectCreation init");
}
public ObjectCreation(String name) {
System.out.println("ObjectCreation " + name + " init");
}
}
class ObjectTest{
static String school="XX大学";
static void printout(){
System.out.println(school);
}
}
public class ChildObjectCreation extends ObjectCreation{
static TestClass testClass3 = new TestClass("staticValue3");
TestClass testClass4=new TestClass("fieldvalue4");
public ChildObjectCreation(String name) {
super(name);
System.out.println("ChildObjectCreation "+name+" init");
}
public static void main(String[] args) {
ChildObjectCreation cd=new ChildObjectCreation("child");
}
}
5.运行结果 ②
第一行:TestClass Static
第二行:TestClass staticValue1 init
第三行:makeInner() invoked
第四行:TestClass staticValue3 init
第五行:TestClass fieldValue1 init
第六行:ObjectCreation child init
第七行:TestClass fieldvalue4 init
第八行:ChildObjectCreation child init
6.分析 ②
总结
好了,今天的内容就到这里,请大家认真思考,及时复习。