精华内容
下载资源
问答
  • 对象创建步骤
    千次阅读
    2019-08-22 07:25:31

    创建对象三步骤

    1. 开辟空间
    2. 初始化对象信息
    3. 返回对象的地址给引用
    更多相关内容
  • JAVA中创建对象步骤

    2022-04-03 16:03:40
    1、判断对象的类是否加载、链接、初始化 2、为对象分配内存:如果内存规整采用指针碰撞的方式,不规整采用空闲列表分配 3、处理并发安全问题: (1)采用CAS配上失败重试保证更新的原子性 (2)每个线程预先...

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

    2、为对象分配内存:如果内存规整采用指针碰撞的方式,不规整采用空闲列表分配

     

    3、处理并发安全问题:

    (1)采用CAS配上失败重试保证更新的原子性

    (2)每个线程预先分配一块TLAB

     

    4、初始化分配到的空间---所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用

    5、设置对象头

     

    6、执行init()方法进行初始化

    属性的显示初始化、代码块中初始化、构造器中初始化

    展开全文
  • 可以看完这个图就懵了,以下是创建对象的六个步骤: 1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、解析、初始化(即判断类元信息是否存在) 如果没有则在双亲委派模式下,使用当前类加载器以...


    要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉,
    比如类的加载过程、CAS、多线程、JVM的GC等等

    首先来看一个图,我大概会根据图中的内容来分享这六个步骤(其实几个步骤不重要,只要包括的内容都在就行):

    在这里插入图片描述

    一、创建对象的六个步骤:

    1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、链接、初始化(即判断类元信息是否存在)

    如果没有则在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为Key进行查找对应的.class文件以此来完成类的加载进内存。在这个过程中,要是找不到要加载的类JVM就会抛出ClassNotFoundException异常,意思就是找不到该类进行加载。

    2、为对象分配内存空间

    首先计算对象占用空间大小,接着在堆中划分一块内存给新对象,如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节。文章结束附有Java八种基本数据类型的所占字节数,分配内存时根据堆中内存是否规整分为:

    内存规整—指针碰撞:如果是规整的,那么虚拟机将采用指针碰撞法来为对象分配内存。

    意思就是所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲那一边挪动一段与对象大小相等的距离,以此来分配内存给对象。如果垃圾收集器选择的是Serial、ParNew这种基于标记 - 压缩算法的,也就是一般使用带有compact(整理)过程的收集器时,就会使用指针碰撞分配方法。

    另外:为什么内存就会是规整的呢?或者为什么内存有不规整的呢?我写了一篇我觉得十分完整的JVM垃圾回收篇

    内存不规整—空闲列表:如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用这种空闲列表法给对象分配内存。

    意思就是虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表找到一块足够大的空间划分给对象实例,这种分配方式就是空闲列表(Free List)。

    3、处理并发问题
    为什么会有这个阶段呢?就是我们都知道堆空间是多个线程共享的,那么多个线程同时去操作堆空间数据时就会存在并发线程安全问题。

    两种方式去解决这种并发安全问题:
    采用CAS失败重试、区域加锁更新的原子性

    CAS算法是这样的:CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包(Java.Util.Concurrent)中的原子类都使用了CAS技术。

    CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。
    CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

    大白话:假如A线程要把共享变量sum的值从1修改为2,那么这时候A线程会先通过地址去获取一次sum的初始值1作为预期值,在修改之前会把之前获取的预期值与当前sum的值进行一次比较,假如两个值相同,那就将1修改为2,如果在A线程修改之前,B线程进入把sum的值提前修改为0了,那么A线程在用预期值去与当前的sum值0比较,显然两个值不相等,此时的A线程就不会修改,会继续去读取sum的值,直到sum为 1 时才进行修改操作。

    每个线程预先分配一块TLAB区域,可以通过-XX:+ /-UseTLAB参数来设定

    TLAB这一块区域是在堆当中Eden(伊甸园)区中的,大概占整个Eden区的1%左右,很小的一块区域,堆为每一个线程单独分配一块TLAB,以此来保证多线程共享数据时是线程安全的。

    4、初始化分配到的空间(对属性初始化,零值初始化)

    这一过程说白了就是:所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用。基本数据类型默认初始化的值在文章下方表格里。

    5、设置对象的对象头

    将对象的所属类(即类的元数据信息)、对象的HashCode、对象的GC信息、锁信息等数据存储在对象头中。这个过程的具体设置方式取决于JVM实现。

    6、执行init方法进行初始化

    可以简单理解成调用构造函数进行显示的赋值,代码中和构造器中初始化。在Java程序的视角看来,初始化才正式开始,初始化成员变量,显示赋值,执行实例化代码块,调用类的构造器,并把堆内对象的首地址赋值给引用变量。

    一般来说(由字节码中是否跟随有invokspecial 指令所决定), new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全创建出来。

    扩展:还有一个clinit方法,这个方法是加载时对类中static静态修饰的属性和静态代码块进行初始化(此过程是在链接阶段的准备阶段)。这是JVM相关的知识了。

    二、对象头的内部结构

    1、创建了Customer()实例 和 Account()实例
    在这里插入图片描述
    一个对象的内存结构包括:运行时元数据、类型指针、实例数据、对齐填充


    2、对象头里包括(64位机器占96位)运行时元数据(Mark Word)(占64位)、类型指针(Klass Point)(占32位)

    (1) 运行时元数据里又包括:哈希值(HashCode)、GC分代年龄、锁状态标志

    哈希值:31位的对象标识hashCode,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。它是一个地址,用于栈对堆空间中对象的引用指向,不然栈是无法找到堆中对象的;

    GC分代年龄(占4位):记录幸存者区对象被GC之后的年龄age,一般age为15(阈值为15的原因是因为age只有4位最大就可以将阈值设置15)之后下一次GC就会直接进入老年代,要是还没有等到年龄为15,幸存者区就满了怎么办,那就下一次GC就将大对象或者年龄大者直接进入老年代。

    锁状态标志:记录一些加锁的信息(我们都是使用加锁的话,在底层是锁的对象,而不是锁的代码,锁对象的话,那会改变什么信息来表示这个对象被改变了呢?也就是怎么才算加锁了呢?

    答案就是改变这个对象的对象头的锁信息来标识已经加锁,下一个线程来获取是获取不到的,底层是通过比对当前的线程的那个值与它所期望的值是否相同,这时候一直自旋直到与期望值相同,相同就获取到锁,反之则进入到阻塞队列等待,这个机制叫做CAS,比较并交换。)
    在这里插入图片描述
    那么怎样查看对象的对象头的信息呢 ?

    第一步:导入第三方依赖

        <dependency>
          <groupId>org.openjdk.jol</groupId>
          <artifactId>jol-core</artifactId>
          <version>0.11</version>
        </dependency>
    

    第二步:打印信息

    System.out.println(ClassLayout.parseInstance(o).toPrintable());
    

    打印结果:

    在这里插入图片描述
    其中VALUE分析:
    在这里插入图片描述

    另外:锁的状态有两位数的空间标识,这样就可以实现用较少的空间去存储更多的信息,
    0 表示不可偏向,1 表示可偏向

    标志位锁状态
    01未锁定
    00轻量级
    10重量级(膨胀)
    01可偏向
    11GC标记

    (2)类型指针:是对方法区中类元信息的引用

    3、实例数据:真实记录一个对象包含的数据,比如说一个person对象,里面可能包含年龄、性别、身高等等,其中数据为字符串的,要引用到字符串常量池。

    想知道jdk8字符串常量池到底在那个地方存储的可以看这里。

    4、对齐填充:填充部分仅起到占位符的作用, 原因是HotSpot要求对象起始地址必须是8字节的整数,假如不是,就采用对齐填充的方式将其补齐8字节整数倍,那么为什么是8呢?原因是64位机器能被8整除的效率是最高的。
    在这里插入图片描述
    另外这个过程还会涉及到逃逸分析。我写了一篇逃逸分析的具体作用,感兴趣可以看看。

    基本数据类型所占字节数默认值包装类名称
    byte1(1字节=8位)0Byte
    short20Short
    int40Integer
    long80LLong
    double80.0dDouble
    float40.0fFloat
    char2‘\u0000’Character
    boolean1falseBoolean

    怎样快速记住这些类型的方法,请看这里。

    有用点个关注,手留余香!😐 😐 😐

    展开全文
  • 创建对象步骤

    千次阅读 2021-07-14 08:49:07
    创建对象步骤图解 二说明 1 判断对象对应的类是否加载、链接、初始化。 虚拟机遇到一条 new 指令,首先去检查这个指令的参数能否在 Metaspace 的常量池中定位到一个类的符号引用,并且检查这个符号引用...

    一 创建对象的步骤图解

    二 说明

    1 判断对象对应的类是否加载、链接、初始化。
    虚拟机遇到一条 new 指令,首先去检查这个指令的参数能否在 Metaspace 的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以 ClassLoader + 包名 + 类名 为 key 进行查找对应的 .class文件,如果没有找到文件,则抛出 ClassNotFoundException 异常,如果找到,则进行类加载,并生成对应的 Class 对象。
    2 为对象分配内存
    首先计算对象占用空间的大小,接着在堆中划分一块内存给新对象。如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节大小。
    - 如果内存规整:指针碰撞
    - 如果内存不规整
      - 虚拟表需要维护一个列表
      - 空闲列表分配
    如果内存是规整的,那么虚拟机将采用的是指针碰撞法(Bump The Point)来为对象分配内存。
    意思是所有用过的内存在一边,空闲的内存放另外一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针指向空闲那边挪动一段与对象大小相等的距离罢了。如果垃圾收集器选择的是Serial ,ParNew这种基于压缩算法的,虚拟机采用这种分配方式。一般使用带 Compact(整理)过程的收集器时,使用指针碰撞。
    如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用的是空闲列表来为对象分配内存。意思是虚拟机维护了一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容。这种分配方式称为“空闲列表(Free List)”。
    选择哪种分配方式由 Java 堆是否规整所决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
    3 处理并发安全问题
    - 采用 CAS 失败重试、区域加锁保证更新的原子性。
    - 每个线程预先分配 TLAB,通过设置 -XX:+UseTLAB 参数来设置(区域加锁机制)。
      - 在 Eden 区给每个线程分配一块区域
    4 初始化分配到的内存
    所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用。
    5 设置对象的对象头
    将对象的所属类(即类的元数据信息)、对象的 HashCode 和对象的 GC 信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于 JVM 实现。
    6 执行 init 方法进行初始化
    在 Java 程序的视角看来,初始化才正式开始。初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内对象的首地址赋值给引用变量。
    因此一般来说(由字节码中是否跟随 invokespecial 指令所决定),new 指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完成创建出来。
    显示初始化 / 代码块中的初始化和构造器初始化是在这一步实现的。 

    三 给对象属性赋值的操作

    a 属性的默认初始化
    b 显示初始化 / 代码块中的初始化
    c 构造器初始化

    四 实战

    1  代码
    /**
    * 测试对象实例化的过程
    *  ① 加载类元信息
    *  ② 为对象分配内存
    *  ③ 处理并发问题
    *  ④ 属性的默认初始化(零值初始化)
    *  ⑤ 设置对象头的信息
    *  ⑥ 属性的显式初始化、代码块中初始化、构造器中初始化
    *
    *  给对象的属性赋值的操作:
    *  ① 属性的默认初始化
    *  ② 显式初始化 / ③ 代码块中初始化 这两个按在代码中出现的顺序进行初始化
    *  ④ 构造器中初始化
    */
    
    public class Customer{
        // 占4个字节,显式初始化
        int id = 1001; // 它的默认初始化是 0
        // 引用占4个字节
        String name; // 它的默认初始化是 null
        // 引用占4个字节
        Account acct; // 它的默认初始化是 null
        {
            // 代码块中初始化
            name = "匿名客户";
        }
        public Customer(){
            acct = new Account();
        }
    }
    class Account{
    }
    2 字节码图解

    五 对象实例化的过程小结

    • 加载类元信息
    • 为对象分配内存
    • 处理并发问题
    • 属性的默认初始化(零值初始化)
    • 设置对象头信息
    • 属性的显示初始化、代码块中初始化、构造器中初始化
    展开全文
  • Java对象创建过程

    万次阅读 2022-03-28 17:54:13
    java对象创建过程、对象的组成、对象头、实例数据、对齐填充、对象创建方式、new关键字、Class类的newInstance方法、Constructor类的newInstance方法、Object类的clone方法、反序列化、无父类的对象创建、有父类的...
  • 老师说,先new了一个对象,在堆内存中开辟空间 然后就是赋默认值(没有静态代码块) 接着就是调用对应的构造函数进栈。 执行隐藏的步骤。 1:super() 2:对非静态变量进行赋显示值 3:执行构造代码块 最后执行构造...
  • java对象创建过程

    千次阅读 2022-02-13 11:29:20
    java语言中我们通过new关键字来创建对象,而这仅仅是语言层面的创建对象,对象创建的原理是怎么样的呢? 我们从jvm的角度分析一下对象创建的过程。 对象的创建大概分为以下几步: 1:通过new关键字定义一个引用...
  • Java创建对象的过程

    千次阅读 2022-02-21 20:02:47
    Java学习总结,Java对象创建过程
  • JVM - 对象创建

    万次阅读 2022-02-02 15:14:05
    JVM - 对象创建
  • Java中new一个对象步骤

    千次阅读 2021-01-27 18:16:34
    Java中new一个对象步骤: 1.当虚拟机遇到一条new指令时候,首先去检查这个指令的参数是否能在常量池中能否定位到一个类的符号引用(即类的带路径全名),并且检查这个符号引用代表的类是否已被加载、解析和初始...
  • 创建一个对象步骤

    千次阅读 2018-01-25 00:11:45
    创建一个对象步骤 A:画图演示 画图说明一个对象创建过程做了哪些事情? 示例代码: class Demo1_Student { public static void main(String[] args) { Student s = new Student(); s.show(); } } class...
  • JVM-JAVA对象创建的五个步骤

    千次阅读 2020-06-29 10:03:01
    对象创建的五个步骤 1、类加载检查 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有...
  • 创建对象步骤和方法

    千次阅读 2018-05-21 16:10:34
    创建对象步骤①为对象分配内存空间,将对象的实例变量初始化为其变量类型的默认值②如果实例变量在声明时被显式的初始化则将初始化值赋给实例变量③调用构造方法④返回对象的引用创建对象的方式①类名 对象名=new ...
  • vlan概述及静态vlan创建步骤

    千次阅读 2021-08-06 18:23:11
    文章目录一、VLANVLAN管理方式静态VLAN的创建步骤静态vlan创建总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、VLAN 工作原理:一个VLAN=一个广播域=逻辑网段(子网) VLAN好处: 1.隔离了广播域 2.安全...
  • Java中创建一个对象步骤

    千次阅读 2019-04-18 22:13:53
    画图说明一个对象创建过程做了哪些事情? Student s = new Student(); 1,Student.class加载进内存 2,声明一个Student类型引用s 3,在堆内存创建对象, 4,给对象中属性默认初始化值(基本数据类型为0,引用数据类型为...
  • 用Java创建对象数组

    千次阅读 2021-02-12 09:46:26
    这就是你得到NullPointerException的原因你需要单独创建对象并分配引用。在Java中创建数组有3个步骤 -声明 - 在此步骤中,我们指定数据类型和要创建的数组的维度。但请记住,我们还没有提到尺寸的大小。他们是空的。...
  • 步骤: 获取类对象; 通过类对象获取一个构造器对象; 通过构造器对象获取实例对象。 TestReflection2.java package study; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTarget...
  • 核心提示:Java 是面向对象的语言,不可避免的,“对象”这个概念是 Java 语言的核心部分,这里来简单讨论一下在 Java 中创建一般对象的方法。 总结下来有以下4种创建对象的方法:使用 new 关键字调...Java 是面向...
  • Java中4种创建对象的方法

    千次阅读 2022-04-23 18:20:10
    4种创建对象的方法: 使用 new 关键字调用对象的构造器; 使用 Java 反射的 newInstance() 方法; 使用 Object 类的 clone() ...Java 反射中有一个 newInstance() 方法,可以创建对象步骤如下:获取要创建的类的 Cl
  • Java创建对象的4种方式

    万次阅读 2018-01-01 18:33:38
    使用new关键字通过new关键字直接在堆内存上创建对象,这样很方便的调用对象的有参和无参的构造函数.Student stu1 = new Student("lihua"); Class反射调用使用Java中反射特性,来进行对象创建。使用Class类的new...
  • 子类对象创建过程

    千次阅读 多人点赞 2016-03-16 20:50:39
    Java对象构造过程 类初始化的时机 初始化类时的操作
  • Java程序运行和对象创建过程简述

    千次阅读 2017-06-22 22:12:47
    Java中一个对象创建分为两个步骤: 加载类,创建对象。 加载类是将所写的程序.java文件编译生成的.class文件加载到内存中,保证了对象创建的预置环境。类加载完毕后才可以创建该类的对象。 第一步:加载类 1. 当开始...
  • ① 最常见的方式就是直接 new 加构造器的方式创建 ② 变形一:XXX(类名). 静态方法,本质这种方式还去调用类中构造器,比如说:单例模式、日历类(Calendar) 和一些工具类等等。 ③ 变形二:XXXBuilder / ...
  • UG工程图模板创建步骤

    千次阅读 2020-08-19 10:55:53
    UG工程图模板创建步骤,看完这篇文章就懂了 UG工程图模板的创建,分为模板文件创建和记事本内容修改两方面。本篇UG教程就教大家UG工程图模板的创建步骤。一、UG工程图模板创建1、通过CAD图纸模板创建UG8.0...
  • Java创建对象的四种方式

    万次阅读 多人点赞 2016-05-09 16:47:56
     另外,如果我们不想利用默认构造器来创建java对象,而想利用指定的构造器来创建java对象,则需要利用Construtor对象,每个Construtor对应一个构造器,为了利用指定构造器来创建java对象,需要如下三个步骤: ...
  • Java中new和反射创建对象的区别(底层)

    千次阅读 多人点赞 2020-11-17 16:25:53
    Java中new创建对象 图来自知乎 如果我们在代码中如果写了一段 A a = new A(); 在JVM中会帮你做的事情有以下: JVM把类的.java文件编译为一个.class的字节码文件 类加载器把.class文件加载进jvm的内存中,一个Class...
  • JS创建对象的几种方法

    千次阅读 2018-07-29 17:41:16
    自己认为目前能较好理解的创建对象方法,可能在某些方面不是最优的方法 // 1. 创建使用函数创建(工厂模式) function Person(age,name){ this.age = age || void 0; //void 0 相当于 undefined ,,自己设置好...
  • 面向对象程序设计步骤

    千次阅读 2017-08-21 10:03:09
    面向对象程序设计的第一步,就是在问题领域中识别出有效的对象,然后从识别出的对象中抽象出类来。面对纷繁复杂的现实问题,往往存在多种对象划分的方式,而不同的划分会带来类的设计以至于程序结构的各种不同。对象...
  • Java有哪些创建对象的方式? 1、用new关键字创建对象,需要使用构造器。 2、使用反射机制创建对象,用Class类或Constructor类的newInstance()方法。 3、通过object类的clone方法 4、使用反序列化
  • 对象创建与销毁 Python中已双下划线开头和结尾的方法是特殊方法,分别对应对象的一些特殊行为。看过《参考手册》对于对象行为与特殊方法的系统解释,这里整理一下笔记。 这里主要介绍python中对象创建、初始化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 902,211
精华内容 360,884
关键字:

对象创建步骤

友情链接: testwindows.zip