欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java中构造方法和代码块的执行顺序

程序员文章站 2023-12-09 20:08:09
PS:这两天学了构造方法和代码块,于是把上课学到的东西和笔记做一个整理,归纳一下Java中构造方法和代码块在创建对象的时候执行顺序。废话不多说,上才艺。首先了解一下构造方法和代码块:构造方法构造法和类名一致,其功能主要是完成给对象初始化构造方法又分为两种:1.空参构造2.有参构造二者的区别在于,你在创建对象的时候有没有写参数,写了参数就调用有参构造,没写就调用空参构造。初始化块Java中的初始化块在创建Java对象时隐式执行,并且是在构造函数之前执行。初始化块与构造方法本质....

PS:这两天学了构造方法和代码块,于是把上课学到的东西和笔记做一个整理,归纳一下Java中构造方法和代码块在创建对象的时候执行顺序。废话不多说,上才艺。

首先了解一下构造方法和代码块:

构造方法

构造法和类名一致,其功能主要是完成给对象初始化

构造方法又分为两种:

1.空参构造
2.有参构造
二者的区别在于,你在创建对象的时候有没有写参数,写了参数就调用有参构造,没写就调用空参构造。

初始化块

Java中的初始化块在创建Java对象时隐式执行,并且是在构造函数之前执行。

初始化块与构造方法本质上是一样的,都是传地址,并为对象属性进行初始化

初始化块也分为两种:

1.静态初始化代码块
2.非静态代码块
二者语法上的区别是有无static修饰。具体用法区别暂时不做区分。

了解了构造方法和初始化块功能,那么问题来了,同样是为对象进行初始化,他们的先后顺序是怎么样的呢?我们举一个例子来简单了解一下:

public class Fu01 {
	//构造方法
	public Fu01() {
		System.out.println("父类构造方法");
	}
	//非静态代码块
	{
		System.out.println("父类非静态代码块");
	}
	//静态代码块
	static {
		System.out.println("父类静态代码块");
	}
}

public class Test01 extends Fu01{
	//构造方法
	public Test01() {
		System.out.println("子类构造方法");
	}
	//非静态代码块
	{
		System.out.println("子类非静态代码块");
	}
	//静态代码块
	static {
		System.out.println("子类静态代码块");
	}
	public static void main(String[] args) {
		new Test01();
	}
}

代码运行结果:
Java中构造方法和代码块的执行顺序

通过观察结果我们会发现,当我们创建Test01对象的时候,首先调用静态代码块,然后调用父类构造方法,之后再调用非静态代码块,最后调用子类的构造方法。

当然,可能这个例子太简单了,没有属性,没有普通方法,那么我们换一个复杂点的例子:

//创建父类Person
public class Person
{
	String name;
	int age;
	String sex;
	
	public Person()
	{     this("zhangsan");
		System.out.println("构造器Person()被调用");
		sex ="Male";
		System.out.println("name="+name+" ,age="+age+" ,sex="+sex);
	}
	public Person(String theName)
	{	this("lisa",20);	
		System.out.println("构造器Person(String theName)被调用");
		this.name = theName;
		System.out.println("name="+name+" ,age="+age+" ,sex="+sex);
	}
	public Person(String theName,int theAge)
	{		
		System.out.println("构造器Person(String theName,int theAge)被调用");
		this.name = theName;
		this.age = theAge;
		System.out.println("name="+name+" ,age="+age+" ,sex="+sex);
	}
	//初始化块
	{
		this.name = "Tony Blair";
		this.age = 50;
		this.sex = "Female";
		System.out.println("Person初始化块执行后:name="+this.name
			+" ,age="+this.age+" ,sex="+this.sex);
	}	
}
//创建子类Teacher
public class Teacher extends Person{	
	String department;//部门
	
	int schoolAge;//教龄
	
	public Teacher()
	{
		System.out.println("构造器Teacher()被调用");
	}
	
	public Teacher(String name)
	{
		//调用父类中的构造器Person(String theName)
		super(name);
		System.out.println("构造器Teacher(String name)被调用");
	}
	
	public Teacher(int theSchoolAge)
	{		 
		this.schoolAge = theSchoolAge;
    	System.out.println("构造器 Teacher(int theSchoolAge)被调用 	schoolAge = "+	schoolAge);
	}
	
	public Teacher(String dept,int theSchoolAge)
	{
		//调用本类中重载的构造器Teacher(int theSchoolAge)
		this(theSchoolAge);
		department = dept;
	System.out.println("构造器 Teacher(String dept,int theSchoolAge)被调用 	department = "+	dept);	
	}		
	//初始化块
	{
		this.department = "教务部";
		System.out.println("Teacher初始化块执行后:name="+this.name
			+" ,age="+this.age+" ,sex="+this.sex+",department ="+this.department);
	}	
}

//创建测试类TestInit
public class TestInit
{
	public static void main(String[] args)
	{
		System.out.println("------------------------------------");
		Person t1 = new Teacher();
		System.out.println("");
		
		System.out.println("------------------------------------");
		Person t2 = new Teacher("Tom");
		System.out.println("");
		
		System.out.println("------------------------------------");
		Person t3 = new Teacher("财务部",20);
	}	
}

代码有点多,可以自行复制粘贴运行,这里我直接上内存图进行分析:
Java中构造方法和代码块的执行顺序
构造方法压栈运行,最上面的先被调用,最下面的最后被调用。而初始化块是再调用构造方法之前就运行了。
当然,我们也可以用V型图进行分析:
Java中构造方法和代码块的执行顺序
实线表示创建对象的调用过程,虚线表示构造方法压栈的过程。

本文地址:https://blog.csdn.net/qq_41841247/article/details/107091272