new 一个实例,如果没加载过就先加载,加载过了就开始类实例化。
- JVM类加载过程
- 加载
把class字节码通过类加载器加载到内存中。
加载非静态内容到方法区
加载静态内容到方法区
- 验证
验证加载到内存的字节码是否符合虚拟机规范。 - 准备
主要是为类变量(static)分配内存并赋予初值。
我认为 final static
- 解析
将常量池内的这个类中的类名、方法名、常量名的符号引用,替换为直接引用。 - 初始化
这个阶段主要是对类变量(static)初始化。
- 类构造器:区别于实例构造器,类构造器负责类在加载时的初始化阶段,对类变量(static)赋予真实值并调用类方法块(static{})。
- 在类加载的时候触发的时候并不会一定执行初始化,例如:
System.out.println(Sun.class),执行了类加载,但是没有进行初始化,在真正使用类的时候才会触发初始化,例如:Sun.staticFun()。public final static修饰的变量A如果没有在声明时赋值,就要在static{}内赋值,而且调用这个变量A的时候会触发类初始化,如果变量A在声明时就赋值,那么调用变量A的时候不会触发类的初始化,我这种A是在准备阶段被分配内存时一同赋值的(没有确切查资料,如果错误,恳请指正)。
- 创建类实例的流程
- 类没加载先加载
- 按父子、代码顺序执行赋值静态变量、执行静态方法块
- 在堆内存开辟内存,分配内存地址
- 在堆内存中创建实例变量并进行默认初始化
- 按父子、代码顺序执行实例变量赋值、构造块{}调用、构造器调用
- 将内存地址赋给栈内存中的实例变量