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、字类的构造方法
如果说的有问题或者有瑕疵,希望各位朋友积极指正,谢谢
本文地址:https://blog.csdn.net/weixin_43277309/article/details/108036159
上一篇: JVM运行时内存数据区域布局
下一篇: 香港景点排行 香港五大必去景点