java对象的初始化顺序

java对象的初始化顺序(详细解释)

前言

小伙伴们好,今天我们来分析一下java对象的初始化顺序。下面的内容是我自己悟了很长时间悟出来的。我的几个舍友看了这篇文章后说感觉对他们帮助很大,希望也能给大家带来帮助。对象初始化顺序很多小伙伴们容易迷惑的一个点,也是大学期末考试一个很重要的考点。下面我通过几道例题,教大家如何分析。分析过程中文字有点多,请大家耐心看,边看边思考并去看题目的代码。好了,废话不多说了,我们开始吧。

一、需要记住的几个原则

  1. static结构随着类的加载而加载,并且在一个类中只加载一次。
  2. 调用构造器时,一定要先解决成员变量问题。等把成员变量全部初始化完毕后,再去调用该类的构造器。
  3. 调用子类构造器时,一定要注意,如果子类没有显式调用父类构造器,那么默认是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.分析 ②

在这里插入图片描述
在这里插入图片描述

总结

好了,今天的内容就到这里,请大家认真思考,及时复习。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值