JVM堆中对象是如何创建的?

一、什么时候会创建对象

1、使用new关键字创建对象
Student student = new Student();

2、使用Class类的newInstance方法(反射机制)
Student student2 = (Student)Class.forName(“Student类全限定名”).newInstance(); 
// 或者
Student stu = Student.class.newInstance();

3、使用Constructor类的newInstance方法(反射机制)

public class Student {
    private int id;

    public Student(Integer id) {
        this.id = id;
    }

    public static void main(String[] args) throws Exception {
        // 首先得到要实例化类的构造器(有参)
        Constructor<Student> constructor = Student.class
                .getConstructor(Integer.class);
        Student stu3 = constructor.newInstance(123);
    }
}

4、使用Clone方法创建对象
无论何时我们调用一个对象的clone方法,JVM都会帮我们创建一个新的、一样的对象,特别需要说明的是,用clone方法创建对象的过程中并不会调用任何构造函数。

public class Student implements Cloneable{
    private int id;

    public Student(Integer id) {
        this.id = id;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }

    public static void main(String[] args) throws Exception {
        Constructor<Student> constructor = Student.class
                .getConstructor(Integer.class);
        Student stu3 = constructor.newInstance(123);
        Student stu4 = (Student) stu3.clone();
    }
}

5、使用(反)序列化机制创建对象
当我们反序列化一个对象时,JVM会给我们创建一个单独的对象,在此过程中,JVM并不会调用任何构造函数。为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

二、简述对象创建过程

在这里插入图片描述

1、当虚拟机遇到new指令(new关键字,反射,clone等)会触发对象的创建。首先会判断new的对象是否能够在运行时常量池中找到对应类的类名(类的符号引用)

2、检查类是否被加载、解析和初始化过,如果没有,则执行相应的类加载过程

3、为新生对象分配内存,内存的分配方式有两种:指针碰撞、空闲列表
指针碰撞:
假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边,中间放着一个指针作为分界的指示器,那么当分配内存时仅需移动指针即可。
空闲列表:
维护一个列表,记录那些内存可用,分配时找出一块足够大的空间进行划分,并更新列表记录。

**选择:**分配方式的选择依赖于内存大小是否规整,内存大小的规整,依赖于垃圾收集器是否带有压缩整理功能(垃圾回收算法不一样)。 
  如果使用的是指针碰撞方法,还需要注意并发情况下,内存的分配是否是线程安全的。一般使用加同步块的方式和本地线程分配缓冲这两种方式解决线程安全的问题

4、内存分配完毕后,JVM会对其进行默认初始化(这也是对象的实例变量不需要初始化就可以使用的原因)

5、从JVM的角度来看,一个对象就此创建完毕,但是从程序的角度来看,一个对象的创建才刚刚开始,它还没有运行(实例初始化方法),所有的字段都还为默认值。只有运行了之后,一个真正可用的对象才算产生出来。

参考:https://blog.csdn.net/championhengyi/article/details/78778575

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值