目录

前言

一、类的实例化是什么?

二、类是如何进行实例化的?

总结


前言

文章主要讲述类和对象的关系及对象的实例化过程在内存中的体现。

一、类的实例化是什么?

类实例化的结果就是生成类的对象。下面看一下类和对象的定义:

是对现实生活中一类具有共同属性和行为的事物的抽象。

对象是能够看得到摸的着的真实存在的实体。

简单理解,可以把我们生活中的一些模具当作类,那么根据模具制作出来的具体的事物就是对象,模具定义了这类对象的属性和行为,创建对象的过程就叫做类的实例化。

二、类是如何进行实例化的?

类的实例化主要分为两个部分,类的加载初始化和对象的初始化。

要创建类的对象实例需要先加载并初始化该类,main方法所在的类需要先加载和初始化;类初始化就是执行<clinit>方法,对象实例化是执行<init>方法;一个子类要初始化需要先初始化父类;类的实例化能够使类的属性赋予到新对象上。

类的加载指的是将编译后的类的.class文件中的二进制数据经过类加载器处理读入内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.class对象,用来封装类在方法区内的数据结构。

类的加载过程:加载->验证->准备->解析->初始化

加载:通过类的全限定名获取类的二进制字节流,将字节流所代表的静态存储结构转化为方法区的运行时数据结构,在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口。

验证:主要是确保加载类的正确性,包括文件格式的验证、元数据验证、字节码验证和符号引用验证等。

准备:为类变量分配内存并设置初始值,注意这里的初始值只是数据类型的默认值而不是代码中被显示赋予的值。

解析:主要是讲符号引用转化为直接引用。符号引用只是用来区分目标的一个代号,直接引用和虚拟机的内存有关,比如指针、相对偏移量等。

初始化:执行类构造器的<clinit>方法,对静态变量静态代码块进行初始化赋值,这里赋予的是程序中定义的初始值,注意和准备阶段区分。

对象的初始化

  • 在方法区加载类;
  • main方法入栈,在栈内存申请空间,定义了一个对象的引用
  • 在堆内存中开辟对象空间,分配对象地址;
  • 在对象空间中,对对象的属性(包括变量、初始化块)进行默认初始化(根据数据类型赋初始值)
  • 构造方法进栈,进行对象属性的显示初始化(程序中定义的初始值)
  • 初始化完成后,将堆内存中的地址赋给引用变量,构造方法出栈;

  

 

总结

类的实例化过程,首先进行类信息的加载初始化,包括静态变量和静态初始化块的初始化(静态变量、静态初始化块:决于它们在类中出现的先后顺序);然后加载main方法,进行对象的变量及初始化块的默认初始化(变量、初始化块:决于它们在类中出现的先后顺序;最后进行构造器的初始化。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐