我相信,大家很多有不了解对象的创建过程的,其实,我之前也是一知半解,所以,系统地看了一下,认识一下,这个到底是什么过程。
先整体说,我们再拆开。
整个创建过程,包括两步,一步是初始化,一步是实例化。
在使用一个对象的时候,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完成类的初始化。
实例化的时候,java虚拟机会为其分配内存来存放自己和从父类继承过来的实例变量。 在为这些实例变量分配内存的同时,这些实例变量先会默认被赋予默认值(零值)。在内存分配完成之后,java虚拟机才会对新创建的对象赋予代码中给定的值。
public class Parent1 {
public static String paretStaticField = "父--静态变量";
public String tempField = "父-临时变量";
static {
System.out.println(paretStaticField);
System.out.println("父----静态初始化块");
}
{
System.out.println(tempField);
System.out.println("父类---初始化块");
}
public Parent1() {
System.out.println("父类---构造器");
}
}
public class Child extends Parent1{
public static String childField = "子---静态变量";
public String tempChildField = "子---变量";
static {
System.out.println(childField);
System.out.println("子---静态初始化块");
}
{
System.out.println(tempChildField);
System.out.println("子---普通初始化块");
}
public Child() {
System.out.println("子--构造器");
}
public static void main(String[] args) {
System.out.println("子类---main方法");
Child child = new Child();
}
}
输出:
父--静态变量
父----静态初始化块
子---静态变量
子---静态初始化块
子类---main方法
父-临时变量
父类---初始化块
父类---构造器
子---变量
子---普通初始化块
子--构造器
现在通过例子来看,怎么样,是不是一目了然。
所以,总结一下,类的初始化顺序如下:
父类静态变量/静态初始化块->子类的静态初始化块和静态初始化变量->父类成员变量/方法块->父类构造器->子类成员变量/方法块->子类构造函数.
这就是类初始化顺序。现在了解了吧。
然后,我们再看一下,内存是怎么分配的呢?
还是上代码:
public class Test {
public static void main(String[] args) {
Student st = new Student();
st.name = "I am a student";
st.age = 123;
st.study();
}
}
public class Student {
public String name;
public int age;
public void study(){
System.out.println("我在学习中。。。。");
}
}
我们看下这个过程。
第一步,JVM去方法区查询Test类的代码信息,如果有直接调用,没有的话使用类的加载机制把类加载进来。
第二步,JVM看到了main方法,进入main方法,看到了 Student st = new Student(). 首先分析Student类,到jvm方法区寻找Student类的相关信息,如果没有,则调用类的加载机制,加载进来。如果有的话,则可以进行加载
第三步,jvm接下来看到了stu, stu是局部变量,存放在栈空间中。
第四步,jvm看到了new student(),则在内存中寻找一片内存区域,new出对象(实例),存放在堆空间中。
第五步,jvm看到了=,把new student()的地址告诉stu变量,stu通过四字节的地址(16进制),引用该实例。
第六步,jvm看到了stu.name='I am student', jvm通过引用实例的name属性,该name属性通过地址指向常量池的“I am a student”
第七步,jvm看到stu.age = 18,由于age是基本数据类型,直接赋值。
第八步,jvm看到stu.study(); 在调用实例方法时,并不会在实例对象中生成一个新的方法,而是通过地址指向方法区中类信息的方法。 如上图所示。
创建一个对象的过程基本上如此,随时拍砖
页面更新:2024-03-31
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号