Java new 一个对象都经历了什么
SunRan

前言

Java在new一个对象的时候,会先查看对象所属的类有没有被加载到内存,如果没有的话,就会先通过类的全限定名来加载。加载并初始化类完成后,再进行对象的创建工作。
由此得出一个new一个java对象包括两个过程:加载和创建

加载类

java是使用双亲委派模型来进行类的加载的,具体查看双亲委派的笔记。

1.加载

由类加载器负责根据一个类的全限定类名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例

2.验证

  • 格式验证:验证是否符合class文件规范
    • 是否以0xCAFEBABE开头
    • 主、次版本号是否在当前虚拟机的处理范围之内

3.准备

在方法区内为类静态变量分配内存并将其初始化为默认值
final 修饰的 static 变量(常量),会直接赋值

4.解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

  • 符号引用:字符串类型的引用,能根据这个字符串定位到指定的对象,如:java/lang/StringBuilder

  • 直接引用:内存地址

    5.初始化

  • 初始化是指为类静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:

    • 声明类变量时指定初始值;
    • 使用静态代码块为类变量指定初始值。
  • 执行static代码块

    static 代码块只有jvm能够调用;
    如果 static 代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。**

创建对象

1.在堆区分配对象需要的内存

分配的内存包括本类和父类的所有实例变量,但不包括任何静态变量

2.对所有实例变量赋默认值

将方法区内对实例变量的定义拷贝一份到堆区,然后赋默认值

3.执行实例初始化代码

初始化顺序是先初始化父类再初始化子类,初始化时先执行实例代码块然后是构造方法

4.定义栈变量

如果new的对象会赋值给一个变量,则会在栈区内定义一个该类型的引用变量,然后将堆区的对象地址赋予它。

  • 本文标题:Java new 一个对象都经历了什么
  • 本文作者:SunRan
  • 创建时间:2022-01-08 18:13:18
  • 本文链接:https://lksun.cn/2022/01/08/Java-new-一个对象都经历了什么/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论