我的老师给了我一个问题:
“在 Java 中创建对象时会发生什么”。
据我所知,内存分配、变量初始化和构造函数方法调用发生在创建对象时。
但我的老师说我几乎是对的。后面的 2 件事都是对的,除了内存堆。相反,他说内存分配发生了。我认为该对象存储在堆中,所以我的老师错了。你认为是吗?
与往常一样,为这类问题找到解决方案的最佳位置是在 Java 语言规范中。
具体来说,从新建实例部分可以理解为,这是新建对象时的顺序,只要不出现异常即可:
Object
. 第一行是指对or的显式调用,或对 的隐式调用super()
this()
super()
。现在,您的老师有可能将内存分配作为实际的操作系统调用来讨论 - 在这种情况下,他是正确的,因为 JVM 管理自己的堆,因此 Java 内存分配不一定会转换为操作系统内存分配调用(尽管可能)。
我会用一个简单的例子来回答这个问题。
假设你有一堂课Car
。现在你写:
Car car;
car = new Car();
第一条语句在堆栈中创建一个引用。car
在第二条语句中,Car
类将被加载到主内存中,然后它将为Car
堆中的成员分配内存。发生这种情况时,成员将使用 JVM 提供的值进行初始化。
除了其他人所说的之外,如果这是对象的第一次使用,那么它的类必须被初始化 - 如JLS中所述(关于新实例创建的部分之前的部分!)。
这基本上涉及将有关类的必要信息加载到内存中,即为Klass
静态变量和方法表创建一个对象。这也可能涉及加载超类和接口。这一切都是由ClassLoader
.
当 JVM 运行程序时,每当创建一个新对象时,JVM 都会为该对象保留作为堆的一部分(该对象将存储在其中)。保留的堆数量取决于对象的大小。
JVM 在堆中映射出这个段来表示正在存储的对象的所有属性。对对象的引用(堆中的地址)由 JVM 保存并存储在允许 JVM 跟踪已在堆上分配的所有对象的表中。JVM 稍后使用这些引用来访问对象(当程序访问对象时)。
当在java中创建对象时,这6个步骤将一一发生--- 1.JVM为引用变量分配8个字节的内存并将默认值分配为null。