java中当一个类实例化的时候会_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");

}

}

运行结果:

3d7aac1e1a17da6441bf18a5ac1d94f0.png

结论:可得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("实例化结束");

}

}

运行结果如下:

6b1aac5741ff1a43b1a24083f066feec.png

结论:例子中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();

}

}

运行结果:

ebdea6229ea154cd2c6d906454cf1591.png

那么可以得出结论:

在显示初始化属性的时候是在构造方法执行完之前完成的。因此在这纠正很多新学Java的朋友或者已经接触Java比较久的朋友,Java类显示初始化的时间不是在构造方法运行结束之后,而是之前。

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

1、父类static修饰的代码(变量,代码块等,如果不止一个,顺序从上到下)

2、字类statc修饰的代码(变量,代码块等,如果不止一个,顺序从上到下)

3、父类的非静态代码(变量,代码块等,如果不止一个,顺序从上到下)

4、父类的构造方法

5、字类的非静态代码(变量,代码块等,如果不止一个,顺序从上到下)

6、字类的构造方法

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

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

希望与广大网友互动??

点此进行留言吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值