Java new 一个对象的时候,首先查看这个对象是否被加载到了内存,如果没有的话,则需要先进行该类的类加载;
假设第一次加载使用这个类,那么new一个对象会发生:
1.加载并初始化类
2.创建对象
一、类加载过程
虚拟机的类加载机制:虚拟机把描述类的class文件加载到内存,并对数据进行校验、转化解析和初始化,最终形成可以被虚拟机直接使用的java类型;
类加载器:java使用双亲委派模型来进行类加载的。
工作过程:类加载器收到类加载请求,它首先不是自己加载这个类,而是先把这个请求委托给父类加载器完成,只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载;
使用双亲委托机制的好处是:能够有效确保一个类的全局唯一性,类加载器进行加载时只会加载其中一个类,如果程序中有多个限定名相同的类不会重复加载。(防止用户自定义类影响jdk原生类)
1.加载
由类加载器负责根据一个类的全限定名读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区 ,然后在堆中实例化一个与目标类型对应的java.lang.Class对象实例;
何时开始加载?
以下几种情况下必须立即对类进行加载
1.使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)的时候,调用一个类的静态方法的时候;
2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没进行过初始化,则需要先初始化;
3.当初始化一个类,它的父类还没有进行初始化,则需要先对父类初始化;
4.当虚拟机启动的时候,用户需要指定一个要执行的主类(包含main的类),虚拟机会先初始化这个主类;
2.验证
确保class文件中的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全;这个阶段的严谨决定了java虚拟机是否会遭受恶意代码的攻击。
验证又分为以下四个阶段:
1.文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理;
2.元数据验证(实质就是语法规范分析):对字节码描述的信息进行语义分析,保证其符合Java语言规范
3.字节码验证
4.符号引用验证
3.准备
为类中的所有静态变量分配内存空间(方法区中分配),并设置初始值;被final修饰的static变量(常量),会直接赋值;
4.解析
将符号引用转为直接引用(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法);
5.初始化
为常量赋值和执行构造器,Java虚拟机会通过加锁来确保类的静态方法仅被执行一次;
最终,方法区会存储当前类类信息,包括类的静态变量、类初始化代码(定义静态变量时的赋值语句 和 静态初始化代码块)、实例变量定义、实例初始化代码(定义实例变量时的赋值语句实例代码块和构造方法)和实例方法,还有父类的类信息引用
二、创建对象
1.在堆区分配对象需要的内存
2.对所有实例变量赋默认值
3.执行实例初始化代码:先父类后子类,先实例代码块后构造方法