类加载、初始化的过程(包括static成员对象)

您所在的位置:网站首页 c类的静态成员是指什么 类加载、初始化的过程(包括static成员对象)

类加载、初始化的过程(包括static成员对象)

2024-07-14 19:07| 来源: 网络整理| 查看: 265

类加载、初始化的过程

因为之前对类加载这块不感兴趣,感觉实际应用中又用不到……但工作后发现并非如此,因此学习总结一下——类加载和初始化的过程让人很绕,有些搞不明白。

首先要明白,类的加载和初始化是两个过程,同样也是总是在一起的两个过程。(菜鸡如我一直都很糊涂)。

1、加载、初始化的含义

当我们第一次使用类时,就会触发类的加载、链接、初始化三个过程。(当然也有的说法会有其他过程,这里我们就简单一点,只说这三个过程)。

类加载,就是查找字节码,从字节码中创建一个class对象(由类加载器执行)链接,就是验证类中的字节码,为静态域分配存储空间初始化,就是为静态成员初始化及静态代码块执行(通俗来说就是赋值)的过程

当这三个对象都完成后,我们才能进行创建对象的操作,也就是new的过程,因为创建对象必须用到类的 Class 对象。

2、类加载、初始化的时机

时机就是第一次使用类时,一般包括三种情况:

A的静态方法(如构造器)首次被访问时A的静态成员(如 i )首次被访问时通过Class类,创建A的class对象

下面列出四种可能的情况:

public Class A extends B{ public static Integer i = 0; public static Integer j = 0; public double k = 0; public double h = 0; static{ print("A被初始化"); } public static void main(String[] args) { //1、new一个对象,这是第一次使用,故A被加载并初始化 A a = new A(); //2、这是第一次使用A的静态成员,故A被加载并初始化 print(A.i); //3、这次有些特殊,这时候A被加载,但并未被初始化 Class aClass = A.class; //4、这时候A被加载并被初始化 Class aClass = Class.forName("A"); } } 3、类加载过程

加载过程,就是创建class对象的过程。

我们都知道类都有一个class对象,假如有一个类A,通过A.class就可以获取这个对象,而实际上class对象就是用来创建对象的。

加载过程,就是创建A的Class对象,为后面创建A的对象做准备。

上面的例子我们知道获取类A的Class对象的两种方法:

一种是常用的A.class一种是Class的静态方法,Class.forName(“类名,需要包含包名”)

这两种方法有一定的区别,就是A.class只会加载类,不会自动的初始化类。

//3、这次有些特殊,这时候A被加载,但并未被初始化 Class aClass = A.class; //4、这时候A被加载并被初始化 Class aClass = Class.forName("A"); 4、类初始化过程

类的初始化过程大家就比较熟悉了,是在加载之后,一般都会进行(A.class这种就没有进行)。

总结一下,初始化顺序为:

先初始化父类(如果父类未被初始化)按顺序初始化静态成员静态代码块执行(与上一步优先级相同,按顺序来,但是一般书写在后面)调用new,创建对象初始化父类的非静态成员变量,调用父类的构造函数按顺序初始化非静态成员非静态代码块执行(与上一步优先级相同,按顺序来,但是一般书写在后面)执行构造器 public Class A extends B{ public double k = 0; public double h = 0; public static Integer i = 0; public static Integer j = 0; //这块代码和静态变量一样,只执行一次 static{ i = 1; } //这块代码和非静态变量初始化时一起执行 { k = 1; } A(){ print("A构造器执行"); } }

如上面类A,它的初始化过程就是。

为 i 赋值0为 j 赋值0为 i 赋值1为 k 赋值0为 h 赋值0为 k 赋值1构造器执行,打印“A构造器执行” 5、特殊情况——静态常量

在类的初始化过程中,有一种特殊情况,就是static final修饰的常量。它不需要初始化,就可以直接访问,因为它是在编译期就准备好了。

注意,需要满足两个条件:

static final修饰常量

比如:

public static final Integer i = 0;

此处的 i 是不需要被初始化,就可以直接访问的。

但是下面:

public static final Integer j = ClassInitializarion.rand.nextInt(1000);

此处的 j 并不是常量,所以需要初始化之后才能访问,也就是说,访问 j 时,会触发类的初始化。

那上面的类A,用static修饰的成员,也是需要初始化吗?

public static Integer i = 0;

是的,对 i 访问时,i 需要先被链接,分配存储空间后,再执行初始化



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3