类加载

程序运行过程

从源文件创建到程序运行,Java程序要经过两大步骤:编译,运行

  1. 编译: 创建完源程序(*.java文件)后,程序会被Java编译器通过javac.exe命令编译为.class文件。Java编译一个类时,如果这个类所依赖的类还没有被编译,编译器就会先编译这个被依赖的类,然后引用,否则直接引用。

  2. 运行:java类运行的过程大概可分为两个过程:

    类的加载;

    执行。

类加载

java程序经过编译后形成*.class文件。字节码文件通过java.exe命令通过类加载器将字节码文件对应的类加载到内存中。

当程序主动使用某个类的时候,如果该类还未被加载到内存中,则系统会通过三个步骤完成对该类的初始化,这三个步骤何在一起,泛泛讲称为类的加载,细讲的话,看作第一步骤
在这里插入图片描述

类的加载:比如说Person类,通过java.exe命令将此类字节码文件加载到内存,并创建一个Class实例,此过程由类的加载器完成
类加载_第1张图片

类的链接:将类的二进制数据合并到JRE中。将类中声明为static的变量设置默认初始值。比如说类中有变量static int n ,在此链接过程中将n赋值为0

类的初始化:JVM负责对类进行初始化。如果定义时给变量n显式赋了个值2,那么在初始化环节,会将n的值有2覆盖0。初始化中有个类构造器方法,不是之前创建类时的构造器,作用是将静态变量有显式值的话,做个初始化操作

public class ClassLoadingTest {
     
    public static void main(String[] args) {
     
        System.out.println(A.m);  //100
    }
}

class A{
     
    static {
     
        m = 300;
    }
    static int m = 100;
}

/**
1.首先将类A字节码加载到内存中,产生一个Class实例,对应方法区中的某一区域
2.链接,将类变量赋值为0
3.初始化,由构造器方法来完成,A的构造器方法由类变量的赋值和讲台代码块中的语句按照顺序合并产生
m = 300;
m = 100;
静态代码块和显式赋值看谁先出现先赋值
*/

ClassLoader 类加载器

类加载_第2张图片

类加载器是用来将类装载进内存的
类加载_第3张图片

对于自定义类,使用系统类加载器进行加载;

调用系统类加载器的getparent(),能获取扩展类加载器;

调用扩展类加载器的getparent(),无法获取引导类加载器;

引导类加载器主要负责加载java的核心类库,我们无法获取到

 @Test
    public void test(){
     
        ClassLoader classLoader = ClassLoadingTest.class.getClassLoader();
        System.out.println(classLoader);

        ClassLoader loaderParent = classLoader.getParent();
        System.out.println(loaderParent);

        ClassLoader parent = loaderParent.getParent();
        System.out.println(parent);
    }

结果展示:

sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@54bedef2
null

你可能感兴趣的:(Java)