精华内容
下载资源
问答
  • Java创建对象的过程简介

    千次阅读 2016-12-02 11:17:42
    简单记录一下Java创建对象的过程,就是new一个对象的时候发生了哪些事情。Java程序执行的过程在此不作说明,对象的创建过程只是程序执行过程的一部分。有关整个程序执行的过程,等熟悉了虚拟机之后在作说明。

    原文链接

    Java创建对象的过程

    简单记录一下Java创建对象的过程,就是new一个对象的时候发生了哪些事情。Java程序执行的过程在此不作说明,对象的创建过程只是程序执行过程的一部分。有关整个程序执行的过程,等熟悉了虚拟机之后在作说明。

    对象创建过程简述

    Java中对象的创建就是在堆上分配内存空间的过程,此处说的对象创建仅限于new关键字创建的普通Java对象,不包括数组对象的创建。

    大致过程如下:

    1. 检测类是否被加载
    2. 为对象分配内存
    3. 为分配的内存空间初始化零值
    4. 对对象进行其他设置
    5. 执行init方法

    检测类是否被加载

    当虚拟机执行到new时,会先去常量池中查找这个类的符号引用。如果能找到符号引用,说明此类已经被加载到方法区(方法区存储虚拟机已经加载的类的信息),可以继续执行;如果找不到符号引用,就会使用类加载器执行类的加载过程,类加载完成后继续执行。

    为对象分配内存

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

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

    • 对于内存绝对规整的情况相对简单一些,虚拟机只需要在被占用的内存和可用空间之间移动指针即可,这种方式被称为指针碰撞。

    • 对于内存不规整的情况稍微复杂一点,这时候虚拟机需要维护一个列表,来记录哪些内存是可用的。分配内存的时候需要找到一个可用的内存空间,然后在列表上记录下已被分配,这种方式成为空闲列表。

    分配内存的时候也需要考虑线程安全问题,有两种解决方案:

    • 第一种是采用同步的办法,使用CAS来保证操作的原子性。
    • 另一种是每个线程分配内存都在自己的空间内进行,即是每个线程都在堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB),分配内存的时候再TLAB上分配,互不干扰。

    为分配的内存空间初始化零值

    对象的内存分配完成后,还需要将对象的内存空间都初始化为零值,这样能保证对象即使没有赋初值,也可以直接使用。

    对对象进行其他设置

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

    执行init方法

    执行完上面的步骤之后,在虚拟机里这个对象就算创建成功了,但是对于Java程序来说还需要执行init方法才算真正的创建完成,因为这个时候对象只是被初始化零值了,还没有真正的去根据程序中的代码分配初始值,调用了init方法之后,这个对象才真正能使用。

    到此为止一个对象就产生了,这就是new关键字创建对象的过程。过程如下:

    检测类是否被加载–>为对象分配内存空间–>初始零值–>进行必要的设置–>调用init方法进行初始化。

    展开全文
  • 文章目录面试题——new一个对象/创建对象的过程第一步,类加载和初始化(第一次使用该类)1. 加载2. 验证3. 准备4. 解析5. 初始化(先父类,再子类)第二步,创建对象1. 在堆区为实例对象分配内存2. 对实例变量赋...

    简洁回答:

    • 第一步,判断常量池是否能定位类的符号引用,并且检查这个符号引用代表的类是否被加载、解析、初始化过。如果没有则执行第一步,如果有则执行第二步
    • 第二步类加载和初始化(初次使用),具体可分为加载、验证、准备、解析、初始化
    • 第三步创建对象,具体可分为实例对象分配内存、赋值、执行实例初始化代码、返回引用

    详细回答

    第一步,判断常量池是否能定位类的符号引用

    判断常量池是否能定位类的符号引用,并且检查这个符号引用代表的类是否被加载、解析、初始化过。如果没有则执行第一步,如果有则执行第二步

    第二步,类加载和初始化(第一次使用该类)

    如果类已经被加载过,则不会执行第一步整个步骤

    1. 加载

    • 类加载器根据类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例

    2. 验证

    • 格式验证:验证是否符合class文件规范,比如必须以魔数0xCAFEBABE开头
    • 语义验证:检查一个被标记为final的类型是否包含子类;检查一个类中的final方法是否被子类进行重写;确保父类和子类之间没有不兼容的一些方法声明(比如方法签名相同,但方法的返回值不同)
    • 操作验证:在操作数栈中的数据必须进行正确的操作,对常量池中的各种符号引用执行验证(通常在解析阶段执行,检查是否可以通过符号引用中描述的全限定名定位到指定类型上,以及类成员信息的访问修饰符是否允许访问等)

    3. 准备

    • 为类中的所有静态变量/常量分配内存空间,并为其设置一个初始值(由于还没有产生对象,实例变量不在此操作范围内)

    public static int value= 1,初始化后的值为 0

    public static final int value= 1,初始化后的值为 1

    4. 解析

    • 将常量池中的符号引用转为直接引用(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法)

    符号引用:比如我们规定了json字符串,"{}“表示对象,”[]“表示数组,”{}“和”[]"就相当于符号引用。在JVM中符号引用是用一组符号描述所引用的目标,比如用0x4000声明这是一个枚举类型


    直接引用:内存地址(指针/偏移量/句柄)

    5. 初始化(先父类,再子类)

    • 执行类构造器 init 方法,init方法包含 为静态变量赋值、执行static代码块

    第二步,创建对象

    1. 在堆区为实例对象分配内存

    • 为实例变量分配内存(包括本类和父类),但不包括任何静态变量

    2. 对实例变量赋默认值

    • 将方法区内对实例变量的定义拷贝一份到堆区,然后赋默认值

    3. 执行实例初始化代码

    • 初始化父类再初始化子类,初始化时先执行非静态代码块(包括非静态初始化块,非静态属性)再执行构造方法

    非静态代码块也叫做实例代码块

    4. 将堆区对象的地址赋值给栈区的引用变量

    • 有类似于Child c = new Child()形式的引用,将堆区对象的地址赋值给栈区的引用变量c


    流程图

    在这里插入图片描述

    展开全文
  • new创建对象的过程

    千次阅读 2018-07-16 08:21:31
    2. 设置新对象的__proto__属性指向构造函数的prototype对象;p.__proto__ = ClassA.prototype;3. 使用新对象调用函数,函数中的this被指向新实例对象: ClassA.call(p); //{}.构造函数(); 4...

    使用new关键字调用函数(var p=new ClassA( ))的具体步骤:

    1. 创建空对象;
    var p= {};

    2. 设置新对象的__proto__属性指向构造函数的prototype对象;
    p.__proto__ = ClassA.prototype;

    3. 使用新对象调用函数,函数中的this被指向新实例对象:
      ClassA.call(p);  //{}.构造函数();          

    4. 将初始化完毕的新对象地址,保存到等号左边的变量中使用new关键字调用函数(var p=new ClassA( ))的具体步骤:

    1. 创建空对象;
    var p= {};

    2. 设置新对象的__proto__属性指向构造函数的prototype对象;
    p.__proto__ = ClassA.prototype;

    3. 使用新对象调用函数,函数中的this被指向新实例对象:
      ClassA.call(p);  //{}.构造函数();          

    4. 将初始化完毕的新对象地址,保存到等号左边的变量中

    展开全文
  • Java创建对象的过程

    千次阅读 2019-02-15 15:03:55
    如果没有,那必须先执行相应类加载过程。 分配内存: 在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存大小在类加载完成后便可确定,为对象分配空间任务等同于把一块确定大小内存从 ...

    在这里插入图片描述

    1. 类加载检查: 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
    2. 分配内存: 在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配方式由 Java 堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
      选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是"标记-清除",还是"标记-整理"(也称作"标记-压缩"),值得注意的是,复制算法内存也是规整的
      在这里插入图片描述
      内存分配并发问题(补充内容,需要掌握)

    在创建对象的时候有一个很重要的问题,就是线程安全,因为在实际开发过程中,创建对象是很频繁的事情,作为虚拟机来说,必须要保证线程是安全的,通常来讲,虚拟机采用两种方式来保证线程安全:

    • CAS+失败重试: CAS
      是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。虚拟机采用CAS 配上失败重试的方式保证更新操作的原子性。
    • TLAB:为每一个线程预先在Eden区分配一块儿内存,JVM在给线程中的对象分配内存时,首先在TLAB分配,当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配
    1. 初始化零值: 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
    2. 设置对象头: 初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
    3. 执行 init 方法: 在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从 Java 程序的视角来看,对象创建才刚开始, 方法还没有执行,所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来
    展开全文
  • new关键字创建对象的过程

    千次阅读 2018-08-09 14:14:52
    题目解析 先看代码 var Func=function(){ ...1、创建一个空对象 var obj=new Object(); 2、设置原型链 obj.__proto__= Func.prototype; 3、让Func中this指向obj,并执行Func函数体。 var r...
  • Java中创建对象的过程

    2019-07-01 22:50:18
    我们来看如下的代码: ... * @description: 对象的生命周期 * @author: YangHang * @create: 2019-07-01 22:21 **/ public class ObjectLifeCycle { public static void main(String[] args) { ...
  • 创建对象的过程(临时对象)

    千次阅读 2019-03-14 20:20:59
    赋值运算符右侧隐式生成临时量,推演CGoods中有符合自身数据类型的构造函数,赋值运算符左侧是生成新对象则会产生优化,以生成临时对象的方式生辰新对象,故调用带一个参数的构造函数。(不需要调用赋值运算符重载...
  • 字面量创建对象的过程

    千次阅读 2014-02-02 00:20:52
    对象字面量形式创建对象的时候 this 的指代对象问题 对象字面量初始化还是在当前语义环境中执行操作的; 如果只有一行:  1.获得和 new Object() 一样的临时对象 obj;  2.解析"属性赋值式",获得一个"属性...
  • JVM类加载机制和创建对象的过程

    千次阅读 2018-02-13 14:29:39
    1、JVM运行和类加载过程一、类的加载机制类加载机制:JVM把class文件加载到内存,并对数据进行校验,解析和初始化,最终形成JVM 可以直接使用的Java类型的过程。主要有三步:加载、连接、初始化。其中连接又可以细分...
  • JavaScript--new创建对象的过程

    千次阅读 2014-09-17 22:40:01
    使用this指针添加类成员缺点: ♪ 将所有初始化语句、成员定义都放到一起,代码逻辑不够 清晰,要实现复杂功能时往往力不从心。 ♪ 因为每创建一个类实例...际上构造函数中定义属性和方法总被重复的创建
  • 说在前面的几句废话 前几天我的文章一直没有更新,大概断了4天左右,因为外出有事,所以给耽搁了,有朋友建议,我可以集中花几天,每天只写文章,这样以后觉得哪里不妥还可以修改,觉得言之有理就...java对象的...
  • Java创建对象的过程总体上可分为四步: Java虚拟机遇到字节码new指令时 ①先看看这条指令对应的参数能否在常量池中定位到类的符号引用 ②若没有,则执行类加载的过程(加载,验证,解析,初始化) ②若有,则为对象...
  • JVM - 对象的创建过程

    千次阅读 2018-11-14 21:22:00
    以new关键字创建对象的过程 执行程序Object obj = new Object(); 当 jvm 遇到new指令时: 1. 首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、验证...
  • java对象的创建过程

    千次阅读 2016-03-28 09:27:04
    java对象的创建过程,java的根本,如下图所示:
  • java创建对象创建过程分析

    千次阅读 2017-11-27 21:10:45
    new Object();的过程
  • JavaScript 使用new创建一个对象的过程

    千次阅读 2018-10-01 12:30:54
    【学习参考】 创建对象有几种方法? 面向对象的小九九 new运算符 JavaScript (new)创建一个对象的过程 用关键字new创建对象 new都做了什么(随笔)
  • 继承关系的对象创建过程

    千次阅读 2016-08-25 19:01:27
    继承关系的对象创建过程
  • JAVA对象创建的过程

    2018-01-21 18:19:27
    JVM对象创建的过程  对于java程序员来说,我们无时无刻不在创建和使用对象。使用new关键字即可快速创建一个对象,其实在new的背后,JVM为我们完成了很多事情。  JVM的字节码解释器在读取到NEW的指令时,会先去常量...
  • Java对象创建的具体过程

    千次阅读 2017-07-09 14:31:59
    Java是一门面向对象的编程...在语言层面上,创建对象(例如克隆、反序列化)通常仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象限于普通Java对象,不包括数组和Class对象等)的创建又是怎样一个过程呢?
  • Java对象的创建过程

    千次阅读 2017-08-24 14:34:09
    1.对象的创建如下图所示为对象的创建过程 当虚拟机遇到new指令时 1) 去常量池当中定位类的符号引用; 2) 检查这个类的符号引用是否被加载,解析和初始化过; 3) 如果没有,则进行类加载的过程,第二节会讲到类...
  • 对象的创建过程(new 的过程

    千次阅读 2017-08-26 11:07:56
    在语言层面上,创建对象通常仅仅是使用一个new关键字而已,而在虚拟机中,对象(仅限于普通Java对象)创建又是怎样一个过程呢?虚拟机遇到一条new指令时,首先将去检查这个指令参数能否在常量池中定位到一个类...
  • Java对象的创建过程详解

    千次阅读 2020-03-30 17:07:27
    本文详细介绍了Java中对象的创建过程,包括对象的创建方式、分配内存、空间初始化、构造方法的执行等。
  • JAVA对象的创建过程

    千次阅读 2019-08-01 18:00:16
    在图中可以清楚看到jvm在创建对象时候执行流程,下面具体讨论一下每个步骤: 在程序进行加载时候,他类信息,常量,静态变量等数据就会存放在方法区(常量池)中。 在执行new操作时候,就会去方法区去...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,505
精华内容 20,202
关键字:

创建对象的过程