java类被实例化之后,里面各类属性的初始化顺序(实例化某个类,那么这个类也会被jvm加载)

有关java类中属性发现java机制的加载顺序。

一、 有关java类中各类属性java机制的执行顺序。

1.1、这是本人开通csdn第一次写的文章,可能语言不够严谨,有错误希望各位朋友指出

二、由于每个类都默认继承Obejct类,所以所例句的例子都是在父子类继承的条件下进行的。

2:解释一下jvm启动加载类的阶段性变化。
2.1、加载阶段:
也就是:这各流程发生在启动类加载器,扩展类加载器,和应用类加载器之间的双亲委托机制(双亲委托机制这里便不在细说,基本原理和思想和简单,各位朋友可以去百度了解一下)
2.2、链接阶段(有些教科书或者网上也称之为连接阶段)
链接阶段又分为,字节码的校验,准备,和解析三个部分
2.3、初始化阶段
就是对类中的成员变量进行显示赋值的阶段(隐式赋值发生在加载阶段)

三 static属性和方法的加载时间

3.1、注意的是static属性和方法是在加载的时候便存放在jvm的方法区里面,而不是在堆里面的。(方法区和堆:堆是用来存放实例化之后的对象或者数组,方法区存放的是一个类的类信息,类的直接父类名,等相关信息)所以static属性或者代码块。在类加载的时候就被执行了或者初始化了。可以通过一下具体例子得知。
说明:(Class.for:是加载某个类的方法,如果有朋友在学习jdbc的时候,用这个方法加载过jdbc的第三方jar包)

public class Test {
	{
		System.out.println("这是匿名代码块");
	}
	static {
		System.out.println("这是静态代码块");
	}
	public static void main(String[] args) {
		System.out.println("com on");
	}
}

运行结果:
在这里插入图片描述
结论:可得static代码块在类加载阶段就被执行,甚至在例子中的main方法执行之前,而静态代码块没有执行;
再看下一个例子

package 博客;
class A {
	{
		System.out.println("这是A的匿名代码块");
	}
	static {
		System.out.println("这是A的静态代码块");
	}
	
}

public class Test {
	
	public static void main(String[] args) throws ClassNotFoundException {
		Class.forName("博客.A");  //加载A类,但是不实例化
		System.out.println("加载结束");
		A a = new A(); //加载并且实例化A类
		System.out.println("实例化结束");
		
	}

}

运行结果如下:
在这里插入图片描述
结论:例子中A类加载了两次,实例化了一次,那么不仅可以得出static代码块在加载的时候运行,而且是第一次加载的时候运行,而非静态代码块(匿名代码块),在实例化的时候才会运行,每实例化一次就运行一次。

类中各中类型属性的初始化顺序(包括父类与字类之间的比较)

由我分析一波,然后再通过例子证明是否正确;
当我们实例化字类对象的时候:
**首先;**加载其父类:那么必然先初始化其static修饰的代码(static从上到下)
**其次:**加载子类:那么必然会初始化其字类的static修饰的代码(static从上到下)
第三:因为字类的构造方法的第一句是super();(如果没有手动修改,默认便是调用父类的无参构造方法)-----?所以此刻是加载父类的构造方法,还是实例化父类的非静态属性呢?啥也不说了,咋们上例子;

package 博客;
class Fu {
	// ******************************************
	{
		System.out.println("这是父类的匿名代码块:可以代替位父类的非静态属性来看");
	}
	// ******************************************
	static {
		System.out.println("这是父类的静态方法");
	}
	// *********************************************
	public Fu() {
		System.out.println("这是父类的构造方法");
	}
	// ******************************************
	
}

class Zi extends Fu {
	// ******************************************
	{
		System.out.println("这是子类的匿名:可以代替位子类的非静态属性来看");
	}
	// ******************************************
	static {
		System.out.println("这是子类的静态方法");
	}
	// ******************************************
	public Zi() {
		//super();//一般都是省略的
		System.out.println("这是子类的构造方法");
	}
	// ******************************************
}


public class Test {
	
	public static void main(String[] args) throws ClassNotFoundException {
		Zi zi = new Zi();
		
	}

}

运行结果:
在这里插入图片描述
那么可以得出结论:
在显示初始化属性的时候是在构造方法执行完之前完成的。因此在这纠正很多新学Java的朋友或者已经接触Java比较久的朋友,Java类显示初始化的时间不是在构造方法运行结束之后,而是之前。

最后由可得初始化时间顺序如下(显示初始化)

1、父类static修饰的代码(变量,代码块等,如果不止一个,顺序从上到下)
2、字类statc修饰的代码(变量,代码块等,如果不止一个,顺序从上到下)
3、父类的非静态代码(变量,代码块等,如果不止一个,顺序从上到下)
4、父类的构造方法
5、字类的非静态代码(变量,代码块等,如果不止一个,顺序从上到下)
6、字类的构造方法

如果说的有问题或者有瑕疵,希望各位朋友积极指正,谢谢

猜你喜欢

转载自blog.csdn.net/weixin_43277309/article/details/108036159