· 本文摘要
· 罗列Java创建对象的各种方式;
· 讲解Java对象创建的流程步骤;

一、Java创建对象的各种方式

· 1. 用关键字new,老少皆知的方法:StringBuffer sb = new StringBuffer();

· 2. 在单例模式(一种设计模式)中创建对象,本质上也是用关键字new,见下面的代码示例:

/*** 单例模式* 饿汉式(静态常量)*/
public class BaseConfig {private final static BaseConfig INSTANCE = new BaseConfig();private BaseConfig () {}//私有构造子public static BaseConfig getInstance() {//在这里返回对象,其实也用了newreturn INSTANCE;}
}

· 3. 在工厂模式Factory、建造者模式Builder(也是设计模式)中创建对象,本质上也是用关键字new

· 4. 反射机制,利用Class.newInstance()。值得注意的是,Class.newInstance()创建对象时的特点有:弱类型,低效率,只能调用无参构造。这里还需要区别Class.forName()Class.forName()返回的是一个类,并不是对象。

· 5. 利用Constructor.newInstance()Constructor.newInstance()可以调用任意构造函数。

· 6. 使用克隆clone(),使用前保证对象实现了cloneable()

· 7. 反序列化。开发中经常会对类实现序列化接口,反序列化支持我们把二进制数据、网络数据转化为Java对象保存在内存中。

· 8. 使用第三方库Objenesis


二、Java创建对象的步骤

· 第一步:检测类是否已经加载
    当JVM即将创建对象前,先去检查常量池中是否有此类的符号引用,并且检查此类是否已加载、链接、初始化。如果没有,需要类加载器来加载此类,参考:类加载器基础知识。

· 第二步:为对象分配内存
    类加载完成以后,虚拟机就开始为对象分配内存,此时所需内存的大小就已经确定了。只需要在堆上分配所需要的内存即可。

具体的分配内存有两种情况:第一种情况是内存空间绝对规整,第二种情况是内存空间是不连续的。

· 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)。

· 空闲列表:如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记 录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。

· 第三步:处理并发安全问题
    由于对象分配的内存是放在堆中的,堆作为线程共享的数据区,当线程数大于1时,会涉及到线程安全问题。需要通过一定的方式来处理并发安全问题。
    第一种是采用同步的办法,为对象空间加锁,使用CAS来保证操作的原子性。
    另一种是每个线程分配内存都在自己的空间内进行,即是每个线程都在堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB),分配内存的时候再TLAB上分配,互不干扰。

· 第四步:初始化分配的空间
    内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头), 如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作解释了对象的实例字段在Java代码中为什么可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

· 第五步:设置对象头
    分配完内存空间,初始化零值之后,虚拟机还需要对对象进行其他必要的设置,设置的地方都在对象头中,包括这个对象所属的类,类的元数据信息,对象的hashcode,GC分代年龄等信息。

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了。但从Java程 序的视角来看,对象创建才刚刚开始<init>方法还没有执行,所有的字段都还为零。

· 第六步:执行init方法(执行构造器)

【JVM】Java对象创建的流程步骤相关推荐

  1. java对象创建的流程到底是什么样子的?new一个对象是真的直接放在堆里吗?其实大有学问!

    目录 对象创建流程图 总结 逃逸分析 什么是逃逸分析? 对象逃逸状态 逃逸分析优化 TLAB区 对象如何进入老年代 有问题可以直接留言讨论~ 对象创建流程图 1.编译器通过逃逸分析,确定对象是在栈上分 ...

  2. Java 并发编程解析 | 如何正确理解Java对象创建过程,我们主要需要注意些什么问题?

    苍穹之边,浩瀚之挚,眰恦之美: 悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 从接触 Java 开发到现在,大家对 Java 最直观的印象是什么呢?是它宣传的 &qu ...

  3. java创建子类对象的步骤_一通Spring骚操作:我敢说没人比我更懂Java对象创建

    一.开篇一问 一个Spring Bean是Java对象吗?那么一个对象是Spring Bean吗? 带着这个问题我们一起来回顾Spring的生命周期流程,彻底了解一个类在Spring中究竟做了哪些操作 ...

  4. Java:对象创建和初始化过程

    1.Java中的数据类型     Java中有3个数据类型:基本数据类型(在Java中,boolean.byte.short.int.long.char.float.double这八种是基本数据类型) ...

  5. Java对象创建的过程及对象的内存布局与访问定位

    这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 1.类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符 ...

  6. JVM —— Java 对象占用空间大小计算

    零. 为什么要知道 Java 对象占用空间大小 缓存的实现: 在设计 JVM 内缓存时(不是借助 Memcached. Redis 等), 需要知道缓存的对象是否会超过 JVM 最大堆限制, 如果会超 ...

  7. 深入理解JVM的对象创建过程

    关于对象创建,有很多种方法.比如可以通过反射,或者通过 new关键字来创建.不管是何种方式,最终都是会创建一个对象.而我们平常工作中最常用的就是通过new关键字来创建对象.对于我们而言,只要new一下 ...

  8. java 对象创建过程_5种创建Java对象的方式

    在本篇文章中,将介绍5种创建Java对象的方式.类是创建对象的基本模板,接下来将介绍5种不同的方式,利用Java类来实例化Java对象. 1. 使用new关键字 ​ 采用new关键字实例化对象是Jav ...

  9. Java对象创建、分配、布局、访问小析(HotSpot虚拟机)(二)

    本文内容总结自周志明先生所编著的<深入理解Java虚拟机-JVM高级特性与最佳实践>此书的经典不必多说.本节内容是对象的内存布局. 在HotSpot虚拟机中,对象在内存中存储的布局可以分为 ...

最新文章

  1. 面试官: 讲讲 Spring 事务有哪些坑?
  2. 安卓打开rpm文件_微信文件如何分享到QQ?教你一招,不管什么手机都能行
  3. Linux使用logrotate来切割日志文件
  4. Windows GPT磁盘GUID结构详解
  5. dir在python中什么意思_python中dir是什么
  6. 醒醒!Python已经支持中文变量名啦!
  7. delphi 打开资源管理器并定位到指定目录下的文件
  8. 报名即将截止,“梧桐杯”大数据应用创新大赛,邀你进入大数据先锋阵营
  9. RDKit入门教程(1)——RDKit 安装 (Win10)
  10. 51单片机开发入门(1)-单片机简介
  11. 计算机全键在线使用说明书,笔记本电脑键盘介绍图,笔记本键盘全部按键功能介绍说明-系统城...
  12. 如何搭建个人博客(详细图解)
  13. 《软件工程》实验一:可行性分析
  14. 网页中留言板的制作案例
  15. nxp的wifi驱动调试
  16. Python编程的一些实例(1)
  17. java启动器_打造java启动器步骤三
  18. “6.1国际儿童节”与开放系统互联7层框架模型
  19. Java对象的持久化,将对象入库保存以及取出转换成对象实例
  20. 毕业设计——基于STM32的智能窗户系统(物联网、智能家居、APP控制、APP显示温湿度等信息、自动工作模式)

热门文章

  1. tf.nn.l2_loss() 与 权重衰减(weight decay)
  2. Pymol BioPython | PDB文件中氨基酸序列的提取
  3. RDKit | 基于不同描述符和指纹的机器学习模型预测logP
  4. 第二十二课.DeepGraphLibrary(三)
  5. envoy实现_微服务之服务治理:Envoy 全局 gRPC 限速服务 lyft/ratelimit 详解
  6. PNAS-2018-根系分泌物香豆素调控微生物群落结构并促进植物健康
  7. pandas使用transpose函数对dataframe进行转置、将dataframe的行和列进行互换(flip the rows and columns in dataframe)
  8. R语言使用coin包应用于独立性问题的置换检验(permutation tests、响应变量是否独立于组、两个数值变量是独立的吗、两个分类变量是独立的吗)、以及coin包的常用置换检验函数
  9. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(双分类变量分组:色彩配置、添加箱图、位置参数调整)实战
  10. R语言临床预测模型的评价指标与验证指标实战:净重新分类指数NRI(Net Reclassification Index, NRI)