new(实例化对象)和对象创建流程

new(实例化对象)和对象创建流程

Java中什么是实例化

在Java语言中使用new关键字创建/构造对象的过程叫做类的实例化,该过程的本质,会在内存空间的堆区申请一块存储区域,用于记录该对象独有的成员变量信息(或者说在栈中存储数据地址)
通俗点就是,实例化就是使用关键字new来创建对象

例如:
Test test = new Test();
类 对象 = new 类();

这种的语句称为创建对象,或者叫做new一个对象
对象是根据类创建的,在Java中使用关键字new创建对象
new Test(); 是 声明一个Test类型的对象,在堆区区域。
其中()是指创建Test类型的对象后,自动调用Test类中的无参构造,来进行成员变量的初始化

对象的创建流程(新)

编译时(javac编译器):java文件 编译成 class(自解码)文件
类加载时(类加载器):class(自解码)文件 加载到 JVM
(这个过程是由类加载器完成的)过程是 class(自解码文件) -> byte[] (字节数组) -> class对象(根据字节数组生成包含类信息的对象)
运行时:class对象 -> 实例

Test test:在栈中创建一个存储地址的空间(负责引用)
new Test();:在堆中创建一个存储空间
new 的过程是根据 class对象(根据字节数组生成包含类信息的对象) 创建对应的对象
查找并判断JVM是否有加载 class对象,如果没有就查找 class文件 加载到 JVM(class文件转换成字节数组,字节数组转换成class对象),然后根据 class对象 生成 实例(在堆中创建一个对象)
Test test = new Test();:在栈中创建存储地址的空间存入在堆中创建存储空间的地址

为什么需要类加载器?

因为在运行时动态创建出来的代理对象是一个字节数组,需要类加载器去加载到jvm创建成class对象,我们才能实例化对象进行操作

Java创建对象的流程

当声明一个对象时,Java会首先在栈(stack)中创建一个引用变量(reference variable),并将其指向堆(heap)中实际的对象。栈中的引用变量保存了堆中实际对象的地址,以便程序能够访问该对象。

在堆中创建对象时,需要先为对象分配内存空间,然后再调用该对象的构造函数进行初始化。在内存分配时,Java会自动管理内存空间的分配和释放,开发者无需手动管理。

垃圾回收

当引用变量不再指向对象时,Java的垃圾回收机制会检测到该对象没有任何引用指向它,自动将其释放,以回收其占用的内存空间。

注意事项

需要注意的是,Java中基本类型的变量并不保存对象的引用,而是直接保存其值,因此基本类型变量的创建和销毁不涉及到堆的操作。

加上静态static的创建流程:

ClassName 中有静态成员,那么在加载这个类的时候就会执行静态成员中的内容,这个过程只会在类加载的时候执行一次。

然后在堆内存中为该对象分配空间,并调用构造方法初始化对象,将对象的地址赋值给 objectName。这个过程包括:

  1. 为对象分配内存空间。
  2. 初始化对象的成员变量,包括静态变量和非静态变量。
  3. 调用构造方法初始化对象,构造方法是在对象初始化的最后一个步骤执行的。
  4. 返回对象的引用。
  5. 最后,把对象的引用地址存储在栈中,以便程序可以通过这个引用访问堆中的对象。

具体来说,对象的创建流程如下:

  1. 在栈中创建一个存储地址的空间,用于存储对象的引用。
  2. 在堆中创建一个存储空间,用于存储对象的属性和方法。
  3. 将对象在堆中的存储地址赋值给栈中的引用。
  4. 在对象的存储空间中进行初始化,包括属性的默认值或者构造函数中指定的初始值。
  5. 如果有其他对象引用了该对象,那么就会增加该对象的引用计数。

如果不讲内存地址的话

  1. 类加载,检查 JVM 是否有加载 class 文件,没有就从 加载 class 文件创建成 class 对象
  2. (静态只执行一次)静态变量(赋值) -> 静态代码块 -> 实例变量(赋值) -> 实例代码块(代码块) -> 构造函数

没有继承的情况,如果有父类的情况先初始化父类
父类静态 -> 子类静态 -> 父类实例 -> 子类实例 -> 父类构造函数 -> 子类构造函数

在Java中,使用关键字new来创建对象,语法如下:

ClassName objectName = new ClassName();

其中,ClassName表示对象的类名,objectName表示对象的引用名称。通过这个语法,可以在堆中创建一个新的对象,并返回该对象在堆中的地址,再将该地址赋值给栈中的引用。

对象的创建流程

在类加载时,先从上往下执行静态代码,后从上往下执行非静态代码
file
file
file