jvm--类的加载,连接,初始化

java是一门静态语言(先编译,再执行),但是它同时具有很多动态语言的特性。java 中类的加载,连接,初始化是程序在运行期间完成的。

  • 加载 : 将编译后的class文件加载到内存。加载的方式有
  1. 从本地系统直接加载class文件
  2. 通过网络远程加载class文件
  3. 从zip,jar中加载class文件
  4. 程序运行期间动态将源文件加载成class文件,参照java设计模式中的动态代理
  • 连接 : 连接分为三个阶段
  1. 验证:验证class文件是否符合jvm规范,因为class文件可以被人为篡改。
  2. 准备:类的静态变量分配内存空间,并赋默认值。(比如int的默认值是0,引用对象的默认值是null)
  3. 解析 :  符号引用转换成直接引用。
  • 初始化:类的静态变量赋值;执行类的静态代码块 static{ }

类的初始化场景:类在主动引用的时候会执行初始化,以下场景是类的主动引用

  1. 创建类的实例,即创建对象
  2. 访问或者修改类的静态变量
  3. 调用类的静态方法
  4. 反射
  5. 初始化一个类的子类(会先初始化父类)
/**
 * Created by IntelliJ IDEA.
 * User: chenzhubing
 * Date: 2019/6/16
 */
public class ClassInitTest {
    public static void main(String[] args) {
        System.out.println(Child.str1);
    }
}

class Parent{
    static String str1 = "hello";
    static{
        System.out.println("parent static block.....");

    }

}
class Child extends Parent{
    static  String str2 = "world";
    static{
        System.out.println("child static block.......");
    }
}

分析下:

  1. 访问Child.str1会执行类的初始化,会执行类的静态代码块内容
  2. 对于静态变量,只有直接定义了该变量的类才会被初始化。因此Child类不会执行初始化
  3. 输出结果:

parent static block.....
hello

      

/**
 * Created by IntelliJ IDEA.
 * User: chenzhubing
 * Date: 2019/6/16
 */
public class ClassInitTest {
    public static void main(String[] args) {
        System.out.println(Child.str2);
    }
}

class Parent{
    static String str1 = "hello";
    static{
        System.out.println("parent static block.....");

    }

}
class Child extends Parent{
    static  String str2 = "world";
    static{
        System.out.println("child static block.......");
    }
}

分析下:

  1. 访问Child.str2会执行Child类的初始化,由于它继承Parent,因此会先执行Parent初始化
  2. 输出结果:

parent static block.....
child static block.......
world

猜你喜欢

转载自www.cnblogs.com/chenzhubing/p/11031735.html