0.前言
在学习类的实例化完整过程中看到了两个比较好的文章:
而其中的名词概念存在使用不够准确的情况,所以本文首先进行概念的区分,再总结下类实例化的完整过程。
1.基本概念区分
(1)无歧义概念
对象:内存上来说是分配在堆上面的一块内存区域。
类:把一类具体事物相同特征,功能/行为抽象为属性与方法过程。
类是对象的模板,对象是类的具体表现。
(2)通俗概念
对象实例/实例对象/X类对象:词性为名词,都是同一个意思,即指某个类实例化出来的对象。
类实例化/对象实例化/实例化对象:词性为动词,都为同一个动作,即通过某个类创建对象的过程。
(3)不同场景下意义不同
①类加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载、类的连接、类的初始化来完成类加载。正常情况下JVM会连续完成这三个步骤,所以有时也把这三个步骤称为类加载或者初始化。
简单说,该场景的类加载包含:类的加载、连接、初始化,所以需要区分使用场景。
②类初始化
参考第二个文章的定义,类初始化与实例初始化是不同的,类的初始化过程:
(1)一个类要创建实例需要先加载并初始化该类
(2)一个子类要初始化需要先初始化父类
(3)一个类初始化就是执行<clinit>()
方法
<clinit>()
方法由静态类变量显示赋值代码和静态代码块组成,且只执行一次- 类变量显示赋值代码和静态代码块代码从上到下顺序执行
<clinit>()
方法,即类初始化方法,系统自动赋予的,在字节码文件中可以看见
③实例初始化
实例初始化就是执行<init>()
方法
<init>()
方法可能重载有多个,有几个构造器就有几个<init>
方法<init>()
方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成- 非静态实例变量显示赋值代码和非静态代码块代码从上到下顺序执行,而对应
构造器的代码最后执行 - 每次创建实例对象,调用对应构造器,执行的就是对应的
<init>()
方法 <init>()
方法的首行是super() 或super(实参列表),即对应父类的<init>()
方法
2.类实例化流程
参考文章一,类/对象实例化过程如下:
①加载类②为对象分配内存③对象属性的默认初始化④设置对象头⑤对象初始化(属性的显示初始化,代码块中的初始化,构造器中的初始化)
其中的第一步则包含1.3中的第一个完整类加载,具体可看原文,写的很好。
而文章一后面的图下部分则与文章二有关<init>()
方法有些矛盾,应该将图中的①和②归为<clinit>()
方法。
最后放张文章一的美图: