
目录
类的加载和初始化
对象的实例化
存在继承关系时实例化顺序
我们都知道,.java文件(java源码)成为可以让计算机执行的机器码,都要经过编译,即:
.java文件------javac(Java编译器)编译------>.class文件;
而.class文件通过Classloader(类加载器)加载到JVM(java虚拟机)中。而在.class文件加载到JVM中的过程中间以及之后,都做了什么工作,以及对象实例化的过程,就是这篇文章的主题。
类的加载和初始化-
加载:载入.class文件到方法区(不一定是从class文件获取,也可能时jar包、动态获取)
在载入.class文件时,JVM会将字节流代表的静态存储结构转化为方法区的运行时数据结构,并在堆中生产一个代表该类的java.lang.Class对象,作为该类方法各种数据的入口;
-
验证:验证class字节流是否符合当前jvm规范,没有安全问题;
-
准备:在方法区为静态变量(类变量/static修饰的变量)分配内存并赋默认值。若为final修饰的静态变量则赋予声明值;
-
解析:将虚拟机中常量池的符号引用(常量名),改为直接引用(内存地址);常量池也在方法区;
-
初始化:执行
方法(类构造器):为静态变量赋值(更改了默认值,注意与赋默认值区分),执行静态代码块。JVM会保证先处理父类的 ()。JVM会保证一个类的 方法在多线程环境下正确地加锁和同步。 方法是用作构造类信息的,不是构造类对象的构造器(这个由构造方法做)。 方法是由编译器自动收集类中的静态变量和静态代码块语句合并产生的。
注:2~4统称连接阶段。
对象的实例化 执行class字节码文件中的
其中构造器
构造方法用于实现功能,和普通方法没有区别。例如,OrderService的有参构造方法,用于在实例化OrderService的对象时,传递id、code的参数:
public class Test {
public static void main(String[] args) {
OrderService orderService = new OrderService(1, 1);
}
}
public class OrderService {
private int id;
private int code;
public OrderService(int id, int code) {
this.id = id;
this.code = code;
}
}
存在继承关系时实例化顺序
上面说到,JVM会保证先处理父类的
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)