前面几篇博文分别介绍了JAVA的Class文件格式、JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能真正看明白)。经常有人问我为什么这么喜欢钻研底层的东西,首先,因为我以前的做硬件的和嵌入式的,兴趣使然;其次,我个人感觉,如果不把上下打通,心里老是有一堵墙过不去,说白了,这是个人因素,与好坏无关(当然,经常有人说,懂底层原理是成为高手的必经之路)。

现在来说一下我当初学习JVM的原因,在学习JAVA之前,我只学过C/C++,当我接触JAVA之后,发现JAVA与C++之间有着巨大的差异,其中最困惑我的就是C++的继承和JAVA的继承实现原理是否一样(对象如何最终定位到字段,无论这个字段是自身的还是继承过来的)?多态的实现机制是否相同?等等。因为之前看过《深度探索C++对象模型》,对C++的对象模型略知一二(一直打算写一个C++对象模型的文章,苦于没时间,后面一定补上),所以我感觉JVM可以解答我的疑惑。

关于对象的创建过程一般是从new指令(我说的是JVM的层面)开始的(具体请看图1),JVM首先对符号引用进行解析,如果找不到对应的符号引用,那么这个类还没有被加载,因此JVM便会进行类加载过程(具体加载过程可参见我的另一篇博文)。符号引用解析完毕之后,JVM会为对象在堆中分配内存,HotSpot虚拟机实现的JAVA对象包括三个部分:对象头、实例字段和对齐填充字段(具体内容请看图2),其中要注意的是,实例字段包括自身定义的和从父类继承下来的(即使父类的实例字段被子类覆盖或者被private修饰,都照样为其分配内存)。相信很多人在刚接触面向对象语言时,总把继承看成简单的“复制”,这其实是完全错误的。JAVA中的继承仅仅是类之间的一种逻辑关系(具体如何保存记录这种逻辑关系,则设计到Class文件格式的知识,具体请看我的另一篇博文),唯有创建对象时的实例字段,可以简单的看成“复制”。

为对象分配完堆内存之后,JVM会将该内存(除了对象头区域)进行零值初始化,这也就解释了为什么JAVA的属性字段无需显示初始化就可以被使用,而方法的局部变量却必须要显示初始化后才可以访问。最后,JVM会调用对象的构造函数,当然,调用顺序会一直上溯到Object类。

至此,一个对象就被创建完毕,此时,一般会有一个引用指向这个对象。在JAVA中,存在两种数据类型,一种就是诸如int、double等基本类型,另一种就是引用类型,比如类、接口、内部类、枚举类、数组类型的引用等。引用的实现方式一般有两种,具体请看图3。此处说一句题外话,经常用人拿C++中的引用和JAVA的引用作对比,其实他们两个只是“名称”一样,本质并没什么关系,C++中的引用只是给现存变量起了一个别名(引用变量只是一个符号引用而已,编译器并不会给引用分配新的内存),而JAVA中的引用变量却是真真正正的变量,具有自己的内存空间,只是不同的引用变量可以“指向”同一个对象而已。因此,如果要拿C++和JAVA引用对象的方式相对比,C++中的指针倒和JAVA中的引用如出一辙,毕竟,JAVA中的引用其实就是对指针的封装。

注:本文为原创博文,转载请注明出处。

图1  对象的创建过程

图2 对象的组成结构

图3  对象引用的两种实现方式

图解JAVA对象的创建过程的更多相关文章

  1. 深入理解Java对象的创建过程:类的初始化与实例化

    摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...

  2. (转)深入理解Java对象的创建过程

    参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...

  3. Java对象的创建过程:类的初始化与实例化

    一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...

  4. 2 Java对象的创建过程

    JAVA中创建对象直接new创建一个对象,对么对象的创建过程是怎样的呢? 程序运行过程中有许多的对象被创建出来.那么对象是如何创建的呢? 一 对象创建的步骤 1 遇到new指令时,检查这个指令的参数是 ...

  5. java --- 对象的创建过程

    java 对象创建的过程 存在了继承关系之后,对象创建过程如下: 1.分配空间.要注意的是,分配空间不光是分配子类的空间,子类对象中包含的父类对象所需要的空间,一样在这一步统一分配.在分配的空间的时候 ...

  6. Java对象(创建过程、内存布局、访问方法)

    (Java 普通对象.不包括数组.Class 对象等.) ​ 对象创建过程 类加载 遇到 new 指令时,获取对应的符号引用,并检查该符号引用代表的类是否已被初始化.如果没有就进行类加载. 分配内存 ...

  7. Java对象的创建过程

    //TODO https://www.cnblogs.com/chenyangyao/p/5296807.html

  8. JAVA虚拟机:对象的创建过程

    简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...

  9. java中对象的创建过程

    public class Test1 { public static void main(String[] args) { new B(); System.out.println("---- ...

随机推荐

  1. 0027 Java学习笔记-面向对象-(非静态、静态、局部、匿名)内部类

    内部类 内部类就是把一个类写在另一个类的内部 用途: 如果一个类只希望它被某一个类访问,那么可以把它定义在另一个类的内部,并用private修饰 内部类可以访问它所在外部类的private成员:但所在 ...

  2. Hadoop 之 MapReduce 框架演变详解

    经典版的MapReduce 所谓的经典版本的MapReduce框架,也是Hadoop第一版成熟的商用框架,简单易用是它的特点,来看一幅图架构图: 上面的这幅图我们暂且可以称谓Hadoop的V1.0版本 ...

  3. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理5

    我们先直接拷贝下blank.html这个页面的代码,顺带先建立一个Home控制器,并添加Index视图.将代码拷贝进去. <!DOCTYPE html> <html lang=&qu ...

  4. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  5. SVN 提交失败: permission denied - txn-current-lock

    执行以下命令即可 sudo chown -R www-data:subversion myproject sudo chmod -R g+rws myproject

  6. Dan Zhang - Visual Studio ALM MVP

    I am a Microsoft Certified Partner specialising in .NET solutions, also worked as an ALM consultant. ...

  7. 帆软报表FineReport SQLServer数据库连接失败常见解决方案

    1. 问题描述 帆软报表FineReport客户端连接SQLServer(2000.2005等),常常会出现如下错误:com.microsoft.sqlserver.jdbc.SQLServerExc ...

  8. JS九大内置对象

  9. Save matrix to a txt file - matlab 在matlab中将矩阵变量保存为txt格式

    Source: Baidu Wenku % Original code has been modified dirMain = 'D:\test\'; fid = fopen([dirMain, 't ...

  10. Macbook被格式化之后

    macbook不小心被手贱格式化了,开机显示一个大问号. 于是查询得到恢复方式是使用command+R. 照做了,试了好几次,那个地球还是卡住不动的.都没有提示让我输入wifi密码. 于是又查了一下, ...