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

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

程序员文章站 2022-04-15 18:34:03
有关java类中属性发现java机制的加载顺序。一、 有关java类中各类属性java机制的执行顺序。1.1、这是本人开通csdn第一次写的文章,可能语言不够严谨,有错误希望各位朋友指出二、由于每个类都默认继承Obejct类,所以所例句的例子都是在父子类继承的条件下进行的。2:解释一下jvm启动加载类的阶段性变化。2.1、加载阶段:也就是:这各流程发生在启动类加载器,扩展类加载器,和应用类加载器之间的双亲委托机制(双亲委托机制这里便不在细说,基本原理和思想和简单,各位朋友可以去百度了解一下)2...

有关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");
	}
} 

运行结果:
java类被实例化之后各类属性的初始化顺序(实例化某个类,那么这个类也会被jvm加载)
结论:可得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("实例化结束");
		
	}

} 

运行结果如下:
java类被实例化之后各类属性的初始化顺序(实例化某个类,那么这个类也会被jvm加载)
结论:例子中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类被实例化之后各类属性的初始化顺序(实例化某个类,那么这个类也会被jvm加载)
那么可以得出结论:
在显示初始化属性的时候是在构造方法执行完之前完成的。因此在这纠正很多新学Java的朋友或者已经接触Java比较久的朋友,Java类显示初始化的时间不是在构造方法运行结束之后,而是之前。

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

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

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

本文地址:https://blog.csdn.net/weixin_43277309/article/details/108036159