方法1、2和3将调用构造函数,这是常规Java创建对象的新机制;方法4、5和6将不会调用构造函数。即使使用了新关键字,讨论构造函数的构造函数的主要方法。
当虚拟机会是新的指令时,首先检查该指令的参数是否可以在常数池中的类别符号引用中放置,并检查是否已加载,解析和初始化代表此符号参考的类,然后必须先执行相应的类加载过程。
通过类加载检查后,虚拟机将为新对象分配内存。可以在加载类后完全确定对象所需的内存大小。为对象对象分配空间的任务等效于将确定Java桩大小的内存划分。
哪种分布方法是由Java堆是否受调节的,以及Java桩是否定期通过采用的垃圾收集器的定期确定。
在虚拟机中,对象创建非常频繁。这只是指向指针方向的位置。就并发而言,这不是线程安全。它似乎是将内存分配给对象。在同一时间,原始指针用于分配内存。
有两种解决方案可以解决这个问题:
当将JVM分配给线程中的对象时,首先将内存分配在TLAB中。当对象大于剩余的内存或TLAB中TLAB的内存时,上述CAS用于内存分配。
内存分布完成后,虚拟机需要将分配的内存空间初始化为零值(不包括对象头)。如果记忆由TLAB分配,则该工作过程也可以提前执行以进行TLAB分配。
此步骤确保对象的实例字段可以直接在Java代码中直接使用,而无需初始值。该程序可以访问与这些字段的数据类型相对应的零值。
以下是各种数据类型的初始值:
字节(字节)0short(short)0int0long0lfloat0.0fdouble0.0dbooleanfalsechar'/uooooo'/uooooo'(null)参考(参考类型)null.dind null.find ofers的信息,对象的哈希代码和对象的哈希代码和GC的GC代理机构物体。该信息存储在对象头(对象标头)中。对虚拟机的当前操作状态进行解密,例如是否有偏置锁,对象头将具有不同的设置。该部分将用对象内存来解释布局。
从上面的工作完成后,从虚拟机的角度来看,已经生成了一个新对象,但是从Java程序的角度来看,对象创建刚刚开始-Method(实例初始化方法,类初始化方法)尚未执行,所有字段仍然为零。因此,一般而言(是否遵循字节代码遵循InvokeSpecial指令,如果没有构造函数的初始化方法,它都不会具有此指令),并且将在执行后执行新指令新说明。< init >类别< init >方法将是父亲的第一个< init >方法的方法)根据程序员的愿望初始化对象。
特别注意,对象初始化和指向堆栈空间的两个步骤是随机的。这对单个示例模式下的双检查锁具有重要影响!它可能直接导致单个示例模式失败!使用JDK1.5后可以避免使用,但是上一本书不能保证!)
在Java虚拟机级别,Java编程语言中的构造函数称为名称称为< init >出现特殊实例初始化方法。
此方法名称由编译器命名,因为它不是合法的Java方法名称,并且不可能通过代码方法实现。实例初始化方法只能通过Java Virtual Machine在初始化期间的指令调用实例的周期,此指令只能在尚未初始化的实例上调用。构造函数的访问权限还将限制从构造函数派生的实例初始化方法。
类或接口可以包含不超过一个类或接口的最大初始化方法。类或接口是通过此方法完成初始化方法。此方法是一种不包含参数的方法,返回类型是无效的,命名。
该名称也由编译器命名,因为它不是合法的Java方法名称,并且不可能直接实现Java程序编码。类或接口的初始化方法由Java Virtual Machine本身调用。没有虚拟机字节代码指令来调用此方法。仅在类的初始化阶段,虚拟机本身只会调用它。
对于类或接口而言,方法不是必需的。如果类/接口中没有静态语句块,则没有对类变量的分配,或者类已声明了类变量,但是它并未清楚地使用类变量初始化语句或静态静态语句或静态静态化的初始化静态化。语句或仅包含静态最终变量的类变量初始化句子,类变量初始化语句是编译常数表达式,那么编译器可能不会生成此类来生成此类。< clinit>()方法。
它是一种对象构造函数方法,这意味着当程序执行结构时,可以执行对象类的构造函数< init >该方法,但是构造函数的方法,即JVM中的类加载 - 验证 - 分析 - 启动阶段< clinit >方法。
将句子块,变量,调用父构建器等的操作放在此方法中,该顺序为:
将静态语句块和静态变量的操作放在此方法中。订单是:
更多的< clinit >使用和规则在类加载文章中部分解释。