jvm对象创建与实例化

创建对象的方式

有以下六种:

  • 直接new、调用Xx的静态方法、使用XxxBuilder/XFactory的静态方法
  • Class的newinstance0 :反射的方式,只能调用空参的构造器,权限必须是public(已经被废弃)
  • Constructor的newinstance(Xxx):反射的方式,可以调用空参、带参的构造器,权限没有要求
  • 使用cloneo:不调用任何构造器,当前类需要实现Cloneable接口,实现clone0
  • 使用反序列化:从文件中、从网络中获取一个对象的二进制流
  • 第三方库Objenesis

使用简单的代码来创建对象,看字节码

package com.lydon.test;

public class ObjectTest {
    public static void main(String[] args) {
        Object o = new Object();
    }
}

形成的字节码如下:
在这里插入图片描述
对字节码的解析如下:

  1. new:判断java.lang.Object的类是否在方法区被加载了,如果没有就要用相应的类加载器加载,确定类空间的大小以及赋初始值,比如boolean就复制false
  2. dup:复制操作数栈中对对象方法区的引用
  3. invokespecial:调用Object的构造器,代码块语句执行初始化
  4. astore_1:将变量名插入局部变量表的位序为1位置中

对象创建的步骤

共分为6步

  1. 判断对象对应的类是否已加载、链接、初始化

    虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的class文件。如果没有找到文件,则抛出ClassNotFoundException异常如果找到,则进行类加载,并生成对应的Class类对象

  2. 为对象分配内存
    计算对象占用空间的大小,在堆中划分一块内存给新对象
    如果是int 或byte或boolean占四个字节,double,float,long,占八个字节,如果为引用类型则统一占四个字节
    在分配过程中,如果是规整的,则使用指针碰撞分配(指针往右移到空闲处)(标记压缩算法类似Serial、ParNew),如果不规整,则就需要维护一个空闲列表,在分配的时候从列表中找到满足空间大小要求的分散区域,并更新空闲为已使用。(标记清除算法类似cms)

  3. 处理并发安全问题
    1、采用CAS失败重试、区域加锁保证更新的原子性
    2、每个线程预先分配一块TLAB

  4. 初始化分配到的空间
    一般来说初始化有三步,1属性默认值的初始化,2、显示初始化/静态代码块初始化 3、构造方法初始化
    这里的是默认值的初始化

  5. 设置对象的对象头
    将对象的类信息,对象的hashcode和对象的gc信息,锁信息等数据存储在对象头中。

  6. init方法的初始化
    显示初始化/执行实例化静态代码块,调用类的构造方法,把堆内对象的首地址复制给引用变量,因此一般来说new之后就会紧接着执行方法,吧对象按照程序员的意愿进行初始化,这样一个真正可用的对象才会完全创建出来。

package com.lydon.test;


/**
* 对象创建的步骤
* 1、加载类的源信息
* 2、为对象分配内存
* 3、处理分配时的并发问题
* 4、属性默认值的初始化
* 5、设置对象头的信息
* 6、属性的显示赋值,代码块,构造方法的赋值。
* 此例子展示了对象的init方法对值的初始化赋值
* 1属性默认值的初始化,2、显示初始化/静态代码块初始化 3、构造方法初始化
*/
public class Customer {
    int id=1000;
    String name;
    Account acount;


    {
        name="客户A";
    }


    public Customer(){
        this.acount=new Account();
    }
}


class Account{
}

可以通过字节码看出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值