对象的属性,方法块,构造器的初始化顺序(+static关键字)

前言

在平时我们创建一个对象的时候,往往都是一个new就完了,这篇文章只要讲的就是在初始化对象的时候,对象的属性,方法,构造方法,带static关键字的属性,还有方法块,等它们的初始化顺序是怎么样的。

先给出结果:
在不考虑继承的情况下:
静态属性和代码块随类的加载而加载,不需要创建对象也会加载。
所以加载的顺序是:
静态属性/代码块---->非静态属性和代码块---->构造器
属性和代码块的顺序与代码的顺序有关。

在考虑继承的情况下
同样静态属性和代码块会随类的加载而加载。
加载的顺序为:
父类静态代码块—>父类静态属性—>子类静态代码块—>子类静态属性—>父类非静态代码块—>父类非静态属性—>父类无参构造方法—>子类非静态代码块—>子类非静态属性—>子类无参构造方法

无继承情况下的对象

非静态属性,非静态代码块,构造器的初始化顺序
//对象
public class Oop {
	public static void main(String[] args) {
		Oop o = new Oop();
	}
	private  Property  pro = new Property("非静态属性") ;
	
	{
		System.out.println("非静态代码块");
	}
	public Oop(){
		System.out.println("无参构造方法");
	}
}
class Property {
	public Property(String str) {
		System.out.println("这是一个"+str);
	}
}

运行结果:属性—>代码块—>构造器。
在这里插入图片描述

考虑到代码的初始化可能跟代码的顺序有关,我们将顺序做个调整
我们将构造器放在最前面,属性放在最后面
代码:

//对象
public class Oop {
	public static void main(String[] args) {
		Oop o = new Oop();
	}
	public Oop(){
		System.out.println("无参构造方法");
	}
	{
		System.out.println("非静态代码块");
	}
	private  Property  pro = new Property("非静态属性") ;
}
class Property {

	public Property(String str) {
		System.out.println("这是一个"+str);
	}
}

结果:代码块—>属性—>构造器
在这里插入图片描述
由结果可知,构造器总是最后才初始化的,属性和代码块的初始化取决于他们的顺序。

非静态属性、代码块、构造器,和静态属性、静态代码块

我们将静态属性和代码块放到最后面
代码:

//对象
public class Oop {
	public static void main(String[] args) {
		Oop o = new Oop();
	}
	
	public Oop(){
		System.out.println("无参构造方法");
	}
	
	{
		System.out.println("非静态代码块");
	}

	static {
		System.out.println("静态代码块");
	}
	
	private  Property  pro = new Property("非静态属性") ;
	private static Property  pro1 = new Property("静态属性") ;
}
class Property {

	public Property(String str) {
		System.out.println("这是一个"+str);
	}
	
	
}

结果:静态代码块—>静态属性---->非静态代码块---->非静态属性---->构造器
在这里插入图片描述
考虑到上面出现的情况,属性和代码块的初始化顺序跟代码的顺序有关,我们可以得到结果,静态属性和代码块会先于非静态属性和代码块执行。

静态修饰的属性和方法只会初始化一次。

有继承情况下的对象

父类和子类-非静态属性、代码块、构造器,和静态属性、静态代码块

父类代码:

//对象
public class Oop {
	public static void main(String[] args) {
		Oop o = new Oop();
	}
	
	public Oop(){
		System.out.println("父类无参构造方法");
	}
	
	{
		System.out.println("父类非静态代码块");
	}

	static {
		System.out.println("父类静态代码块");
	}
	
	private  Property  pro = new Property("父类非静态属性") ;
	private static Property  pro1 = new Property("父类静态属性") ;
}
class Property {

	public Property(String str) {
		System.out.println(str);
	}
	
	
}

子类代码:



//子类
public class SunOop extends Oop {
	public static void main(String[] args) {
		Oop sunOop = new SunOop();
	}
	{
		System.out.println("子类非静态代码块");
	}
	public SunOop(){
		System.out.println("子类无参构造方法");
	}
	static {
		System.out.println("子类静态代码块");
	}
	 Property1 pro2 = new Property1("子类非静态属性");
	 static Property1 pro1 = new Property1("子类静态属性");
}
class Property1 {

	public Property1(String str) {
		System.out.println( str);
	}
}

运行结果:父类静态代码块—>父类静态属性—>子类静态代码块—>子类静态属性—>父类非静态代码块—>父类非静态属性—>父类无参构造方法—>子类非静态代码块—>子类非静态属性—>子类无参构造方法

在这里插入图片描述
由此我们可以直到,在初始化子类的时候,会率先初始化父类的属性和方法。

下面我们再看一下,如果我们不创建对象,初始化的情况。
即main方法中不new对象

	public static void main(String[] args) {
		//Oop sunOop = new SunOop();
	}

结果:
在这里插入图片描述
可以发现,在不new对象的情况下,static方法和属性也是会加载的。

关于static修饰的属性和方法

静态方法会随类的加载而加载。
只会初始化一次。
且在前面初始化。

看代码:
类代码:

package com.dyit.tanruike;

public class Pet {

	//用来保存宠物
	private static Pet[]  pets = new Pet[10]; 
	private static int index =0;
	//宠物的名字
	private String name ;
	
	//添加宠物
	public void add(String name) {
		Pet p = new Pet();
		p.setName(name);
		//添加进数组
		pets[index++] =p ;
	}
	//显示宠物信息
	public void show() {
		for (Pet p : pets) {
			if (p!=null) {
				
				System.out.println(p.getName());
			}
		}
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}		
}

测试类:

package com.dyit.tanruike;

public class PetTest {

	public static void main(String[] args) {
		Pet p1 = new Pet();
		p1.add("猫");
		Pet p2 = new Pet();
		p2.add("狗");
		
		p2.show();
	}
}

结果:
在这里插入图片描述
我们分别创建了两个对象,一个添加的猫,一个添加的是狗,但是最后用第二个对象调用show()方法,也显示了第一个对象添加的猫。
由此,可以看出来static修饰的属性和方法在加载是指挥加载一次,随类的加载而加载,并不是在对象创建的时候随对象的创建二创建。static修饰的属性和方法,是类所具有的。是公共的

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vivien_o.O

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值