Java对象的实例化过程是怎样的?

Java中实例化对象有哪几种方式? 其中,第2种和第3种方式都是使用Java的反射机制来动态创建对象的。在使用反射创建对象时,需要注意异常的处理。 阅读详情

对象实例化过程

对象实例化过程,就是执行类构造函数对应在字节码文件中的 <init>() 方法(实例构造器), <init>() 方法由非静态变量、非静态代码块以及对应的构造器组成。

<init>() 方法可以重载多个,类有几个构造器就有几个 <init>() 方法;

<init>() 方法中的代码执行顺序为:父类变量初始化、父类代码块、父类构造器、子类变量初始化、子类代码块、子类构造器。

静态变量、静态代码块、普通变量、普通代码块、构造器的执行顺序如下图:

具有父类的子类的实例化顺序如下:

底层实现原理

Java是一门面向对象的编程语言,Java程序运行过程中无时无刻都有对象被创建出来。

在语言层面上,创建对象通常(例外:复制、反序列化)仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象限于普通Java对象,不包括数组和Class对象等)的创建又是怎样一个过程呢?

检查符号引用

当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个

类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先

执行相应的类加载过程。

分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。

分配内存时有两种情况对应两种分配方式:

假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着

一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小

相等的距离,这种分配方式称为“指针碰撞”(Bump The Pointer)。

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

选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定。

因此,当使用Serial、ParNew等带压缩整理过程的收集器时,系统采用的分配算法是指针碰撞,既简单又高效;而当使用CMS这种基于清除(Sweep)算法的收集器时,理论上就只能采用较为复杂的空闲列表来分配内存。

线程安全处理

除如何划分可用空间之外,还有另外一个需要考虑的问题:对象创建在虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。

解决这个问题有两种可选方案:

一种是对分配内存空间的动作进行同步处理——实际上虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性;

另外一种是把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。虚拟机是否使用TLAB,可以通过 -XX:+/-UseTLAB 参数来设定。

初始化内存

内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值,如果使用了TLAB的话,这一项工作也可以提前至TLAB分配时顺便进行。这步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,使程序能访问到这些字段的数据类型所对应的零值。

设置对象信息

接下来,Java虚拟机还要对 对象进行必要的设置

例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode()方法时才计算)、对象的GC分代年龄等信息。

这些信息存放在对象的对象头(Object Header)之中。根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了。

执行init构造

但是从Java程序的视角看来,对象创建才刚刚开始——下一步要进行构造函数的调用,即Class文件中的 <init>() 方法还没有执行,所有的字段都为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。

一般来说(由字节码流中new指令后面是否跟随invokespecial指令所决定,Java编译器会在遇到new关键字的地方同时生成这两条字节码指令,但如果直接通过其他方式产生的则不一定如此),new指令之后会接着执行 <init> () 方法,按照程序员的意愿对对象进行初始化。

这样一个真正可用的对象才算完全被构造出来

代码示例

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">package com.interview.module.jvm;

class Parent { 

    static { 
        System.out.println("父类静态代码块");
    }

    { 
        System.out.println("父类普通代码块");
    }

    Parent(){ 
        System.out.println("父类构造器");
    }

    private static int staticNumber = 0;
    private int normalNumber;
}

class Child extends Parent{ 
    static { 
        System.out.println("子类静态代码块");
    }

    { 
        System.out.println("子类普通代码块");
    }

    Child(){ 
        System.out.println("子类构造器");
    }

    private static int staticNumber = 0;
    private int normalNumber;
}

public class NewObject { 
    public  static  void  main(String[] args)  { 
        Child child = new Child();
    }
}

运行结果如下:

 

 

Java类与对象的关系及实例化过程 本文深入探讨了Java中类与对象的关系及实例化过程。类是Java面向对象编程的基本单元,定义了对象的结构和行为,包括属性、方法、构造方法等。对象是类的实例,代表了现实世界中的具体实体,具有状态、行为和唯一标识。类与对象的关系可以理解为模板与实例、抽象与具体、一对多关系等。对象的实例化过程包括类加载、内存分配、初始化零值、设置对象头和执行初始化等步骤。本文还详细介绍了构造方法、this关键字、静态成员以及对象的生命周期等内容。在实际开发中,应遵循类设计原则,如单一职责原则、开闭原则等,合理管理对象的创建和生命 阅读详情

相关推荐

【Java进阶之路】java实例化的五种方式

运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去,用clone方法创建对象并不会调用任何构造函数。和Class类的newInstance方法很像, java.lang.reflect.Constructor类里也有一个newInstance方法可以创建对象。2.使用Class类的newInstance方法。

太阳当空照,花儿对我笑,微风轻轻拂,心情无限好。 1781

Java 对象实例化过程

了解Java对象的实例化过程,方便开发过程中了解对象的加载顺序以及初始化顺序

博客只为自己学习提升纪录所用,如有侵权或不妥之处,还请私信删除!加油 818

IMU数据处理避坑指南:从理论到实践的加速度计重力消除方案

本文详细解析了IMU数据处理中的重力消除技术,从理论基础到实践应用,涵盖了加速度计和陀螺仪的核心问题。通过ROS2实战案例,介绍了静态标定与动态校准的技术对比,以及多传感器融合的进阶策略,帮助开发者避免常见陷阱,提升IMU数据处理的精度和效率。

purple的博客 739

深入JVM了解Java对象实例化过程

加载类元信息为对象分配内存处理并发问题属性的默认初始化(零值初始化)设置对象头信息属性的显示初始化、代码块中初始化、构造器中初始化在没有继承的条件下,实例化一个对象初始化的顺序为:静态成员的初始化静态初始化块成员的初始化初始化块构造器这里面需要注意的是【静态部分只在类加载时初始化一次】如果有继承关系,那么实例化子类对象的初始化顺序为:父类静态成员的初始化父类静态代码块初始化子类静态成员的初始化子类静态代码块初始化父类成员的初始化父类初始化块父类构造器。

写写平时的技术与感想 2953

【ESP32 S3 开发】基于I2S协议驱动INMP441数字麦克风 实现语音采集

注意INMP441的 L/R接地之后才稳定输出数据 否则一直都是0WAV格式说明这里主要是想说wav文件重要的就是生成一个wavhead来标识它是一个wave文件,wave文件的data chunk 中的data部分还是PCM编码格式的数据,直接从I2S读进去就可以,不需要压缩。wav文件的头一般由4个chunk组成。 以16bit深度为例,代码如下。其他深度可以根据注释自行计算。 I2S -> DAC i2s_read()函数,向flash中划分的一个buff当中读入byte数组。以16bit深度为例,一

m0_43395703的博客 1万+

abaqus热力耦合模拟教程学习笔记

学习资源:BV1je4y1a7Ku软件:abaqus2016以m为单位制。

qq_41900477的博客 2万+

Java对象实例化的过程

对象的实例化过程涉及多个步骤,包括类加载、内存分配、初始化等

weixin_44968331的博客 728

从‘最速控制’到代码:深入拆解韩京清ADRC中TD跟踪器的fhan函数(含Matlab/Simulink实例)

本文深入解析韩京清ADRC中的fhan函数,从理论到代码实现,详细拆解其在Matlab/Simulink中的应用。通过分析最速控制问题和非线性TD的连续形式,揭示fhan函数在信号处理和噪声抑制中的独特优势,并提供工程实践中的参数整定和优化技巧。

weixin_42659194的博客 246

【Java】对象的实例化过程

在之前的阶段中,除了加载阶段通过自定义的类加载器可以干预虚拟机的加载过程外,其他的阶段都是虚拟机完全主导,而在初始化阶段才开始根据程序员的意愿执行类的初始化,这个阶段主要完成的工作是执行类构造器方法(),同时虚拟机会保证执行该类的类构造器方法时,其父类的类构造器方法已经被正确的执行,同时,由于类的初始化只进行一次,当多个线程并发的进行初始化时,虚拟机可以确保多个线程只有一个可以完成类的初始化工作, 保证线程安全工作。这样做的目的是为了确保在对象创建时,成员变量都有一个合理的初始值,以防止潜在的运行时错误。

Your_Boy_Tt的博客 1530

FPGA+滨淞CCD实战:手把手教你搭建S7031/S10142成像电路(附避坑指南)

本文详细介绍了使用FPGA驱动滨淞CCD传感器(S7031/S10142)构建高精度成像系统的完整实战流程。内容涵盖核心器件选型、系统架构规划、电路板(焦面板与接口板)设计要点、FPGA Verilog逻辑实现,并提供了从电源管理、信号调理到数据采集的详细避坑指南,帮助读者从零搭建稳定可靠的成像电路。

weixin_29271263的博客 227

从零到一:用AXI DataMover在Zynq MPSoC上实现高效DMA传输(附Vitis HLS驱动示例)

本文详细介绍了如何在Xilinx Zynq UltraScale+ MPSoC平台上使用AXI DataMover实现高效的DMA数据传输。通过解析AXI DataMover架构、Vivado工程配置、Vitis HLS驱动开发及性能优化技巧,帮助开发者快速构建高性能数据传输通道,并提供了可直接复用的代码示例。

weixin_42520796的博客 423

java 实例化对象jvm_Java对象在内存中实例化的过程

Java对象在内存中实例化的过程在讲 Java 对象在内存中的实例化过程前,先来说下在类的实例化过程中,内存会使用到的三个区域:栈区、堆区、方法区。堆区:存储的全部都是对象,每个对象包含了一个与之对应的 class 类的信息。jvm 只有一个堆区(steap),它会被所有线程共享,堆中不存放基本数据类型和对象引用,它只存放对象本身。栈区:每个线程都包含一个栈区,栈中只保存基本数据类型的值和对象以及...

weixin_36360543的博客 1290

TIA博途中通过UDT实现IO地址映射到DB块中的具体方法

TIA博途中通过UDT实现IO地址映射到DB块中的具体方法

Robot_PLC_HMI_Automation 1万+

Java对象的实例化过程

JAVA new流程(实例化过程) java对象的实例化过程

guopeng的博客 3509

最优化方法与数学建模

在本篇博客中,我们将探讨最优化方法在数学建模中的应用。首先,我们将介绍几种常见的最优化方法,如梯度下降、牛顿法和遗传算法。接着,我们将详细阐述这些方法的原理和算法。最后,我们将通过一个数学建模案例,展示如何使用Matlab实现这些方法。本文旨在为大家提供一个清晰的思路,以便更好地理解和应用最优化方法。

YOLO 438

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java对象在内存中实例化的过程

Java对象在内存中实例化的过程 在讲 Java 对象在内存中的实例化过程前,先来说下在类的实例化过程中,内存会使用到的三个区域:栈区、堆区、方法区。 堆区: 存储的全部都是对象,每个对象包含了一个与之对应的 class 类的信息。 jvm 只有一个堆区(steap),它会被所有线程共享,堆中不存放基本数据类型和对象引用,它只存放对象本身。 栈区: 每个线程都包含一个栈区,栈中只保存基本数据类型的值和对象以及基础数据的引用。 每个栈中的数据(基本数据类型和对象的引用)都是私有的,其它栈是无法进行访

youchitang的博客 7781

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

详解JAVA对象实例化过程

1 对象的实例化过程对象的实例化过程是分成两部分:类的加载初始化,对象的初始化要创建类的对象实例需要先加载并初始化该类,main方法所在的类需要先加载和初始化类初始化就是执行<clinit>方法,对象实例化是执行<init>方法一个子类要初始化需要先初始化父类2 类的加载过程类的加载机制:如果没有相应类的class,则加载class到方法区。对应着加载->验证-&gt...

十指波课堂的博客 2762

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

java实例化对象的过程

<br /><br />       学习JAVA这门面向对象的语言,实质就是不断地创建类,并把类实例化为对象并调用方法。对于初学JAVA的人总搞清楚对象是如何实例化的,假如类之间存在继承关系,那就更糊涂了。下面我们通过两个例题来说明对象的实例化过程。<br /><br /><br /><br /><br /> <br />       编译并运行该程序会有以下输出 Static Block Employee Company:china soft Non-Static Block Employee phon

piaojun_pj的专栏 2万+

java 对象实例化过程

知识回顾:      编译: Java源码经编译器编译后成为二进制字节码文件(*.class文件)。      加载:当要使用时将磁盘上的.class文件移入进内存。      运行:由JVM翻译成操作系统可识别的二进制机器码,再在JRE下运行。       对象实例化过程:     1.首先,按需加载需要的 *.class文件,如果已经加载,便不再重复加载;如果没有加载,则加载进内存

yjchen69的专栏 1083

java对象的实例化过程

关于对象的实例化过程: 1.检查类是否加载,如果没有加载就加载这个类,要加载所有父类; 懒式加载(按需加载):如果第一次用到加载,只加载一下.通过ClassPath制定的路径寻找类文件(.class)  加载以后是一个对象,类型是class.获得这个类对象:student.class-->class实例 2.在内存堆中分配对象空间.递归分配所有父类和子类属性空间.先父类型再子类型,属性默认自

avinegar的专栏 1万+

java对象实例化过程分析

我们平时经常随手就new一个对象出来,但是找对象真的这么简单吗?看看下面的分析~ 首先看一下类的生命周期 图中从1到3的过程统称为连接,而1-5这5个过程合起来称为类加载。在一个对象可以使用之前,需要经过类加载和实例化,也就是我们今天的主题“new一个java对象的过程”。那虚拟机在什么时机进行类加载呢?Java 虚拟机规范并没有对其做严格的定义,不同的JVM有不同的实现。而初始化的时机JV

周孙静的博客 1813

Java对象实例化过程

我们通过一个对象的实例化来分析对象实例化的过程: 创建一个Person类: package com.yys; public class Person { public String name; public int age; public void eat(){ System.out.println("吃饭"); } } 再创建一个类来调用Person类 package com.yys; public class App { public s

qq_46027706的博客 487
上一篇: 字典服务的设计与管理
下一篇: Java JNI 使用笔记
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值