首先,什么是类的加载?类的加载由类加载器执行.该步骤将查找字节码(classpath指定目录),并从这些字节码中创建一个Class对象。Java虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。一旦某个类的Class对象被载入到内存,他就被用来创建这个类的所有对象。
类的加载会发生在什么时候呢?所有的类都是在其第一次使用的时候,动态加载到JVM的。当程序创建第一个对类的静态成员的引用时,就会加载这个类。构造方法默认也是静态的,所以new的时候若该类未被加载,则也会进行加载操作。
另外说明下,有继承体系的类也会被自动加载,不管该父类是否会被使用。比如B继承了A。倘若任何类都未被加载,当 new B() 时,首先会将B加载了,随后会将A给加载了。
对象的内存分配及初始化
- public class Demo_Student {
- public static void main(String[] args) {
- Student s = new Student();
- s.show();
- }
- }
- class Student {
- private String name = "张三";
- private int age = 23;
- public Student() {
- name = "李四";
- age = 24;
- }
- public void show() {
- System.out.println("我叫:"+name+",今年"+age+"岁");
- }
- }
1.首先,程序运行时,会将Demo_Student加载进内存,随后,其主方法main入栈。紧接着发现了new Student(),所以又将Student加载进内存
字段信息:存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。
方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。
2.然后在栈内存分配一块空间(Student s),声明Student的引用。new Studetn() 在堆内存开辟空间,进行默认初始化和显示初始化
3.调用构造方法,系统默认调用。构造方法进栈,对对象进行初始化,初始化完成后,弹栈。此时对象已经创建完毕。将其地址值赋值给变量s
4.可通过s其地址值找到对应堆内存空间的实体,调用show方法时,show进栈,其内部有个隐藏的this引用,根据该引用找到堆内存实体,并打印相应内容
5.随后main方法也执行完毕,弹栈,程序执行完毕
总结
Student s = new Student(); 在内存中到底执行了哪些步骤?
1,加载Sutdent.class文件进内存(类加载器)
2,在栈内存为 s 变量申请一个空间
3,在堆内存为Student对象申请空间
4,对类中的成员变量进行默认初始化
5,对类中的成员变量进行显示初始化
6,有构造代码块就先执行构造代码块,如果没有,则省略(此步上文未体现)
7,执行构造方法,通过构造方法对对对象数据进行初始化
8,堆内存中的数据初始化完毕,把内存值复制给 s 变量