类加载

JVM进程被终止的情况:

  1. 运行完正常结束
  2. 执行System.exit()或Runtime.getRuntime().exit()
  3. 遇到未捕获异常或错误而结束
  4. 强制结束JVM进程

类使用/加载三步骤:装载、连接、初始化

类的加载:指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象

类的连接:负责把类的二进制数据合并到JRE中。又分为3个阶段:

  1. 验证/校验:检查载入Class文件
  2. 准备:给类的静态变量分配存储空间并设置初始值
  3. 解析:非必须,将类的二进制数据中的符号引用替换成直接引用

类的初始化:对类的静态变量(声明变量时指定初始值)、静态代码块进行初始化工作。

记住一个过程:先默认值,比如int i就是0,然后按照先后顺序执行代码(含静态代码块)

类的初始化会处理静态变量以及执行静态代码块。

类初始化时机即出现如下任意一种情况都会触发类的初始化(想想单例的懒加载)

  1. 创建类的实例(含new、反射、反序列化)
  2. 调用类的静态方法
  3. 访问某个类或接口的类变量,或为该类变量赋值。
  4. 使用反射强制创建某个类或接口对应的java.lang.Class对象
  5. 初始化某个类的子类。初始化子类,其所有父类都会被初始化、
  6. 运行的主类
  1. final修饰的类变量(已经确定其值),被调用时不初始化该类,如果其值不能确认static final String now = System.currentTimeMills() + “”;这种就会被初始化
  2. ClassLoader#loadClasss方法加载某类,也不会引起该类初始化
  3. Class#forName方法加载某类时,会强制初始化

类加载器

类加载器负责把.class文件加载到内存中,并生成对应的java.lang.Class对象。对于一个加载器,只要加载过并且内存中有,就不会再次加载。

对jvm同一个类:类全限定名+其类加载器,2个都一样才认为是同一个类。

分类

JVM启动时,就会形成3个类加载器:

  1. BootstrapClassLoader,根类加载器,非java语言。读jre的类,通过

        URL[] urLs = Launcher.getBootstrapClassPath().getURLs();

        for(URL url : urLs){

            System.out.println(url.toExternalForm());

   }

类加载_第1张图片

 

  1. ExtensionClassLoader:扩展类加载器,java,是BootstrapClassLoader的子类。读jre/lib/ext下的类
  2. SystemClassLoader:系统类加载器也叫应用类加载器,读-classpath、java.class.path系统属性或CLASSPATH环境变量所指定jar或类,ClassLoader.getSystemClassLoader方法就是获取此类加载器的。
  1. 除了根加载器以外,所有的类加载器都是ClassLoader的子类

类加载器的3种机制

  1. 全盘负责:即一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他类,都由其负责载入,除非显示指定其他加载器。
  2. 父类委托:对应加载器,先让其父加载器加载,父无法处理,再由自己处理
  3. 缓存机制:保证所有加载过的Class都会被缓存,当程序需要使用某个class时,类加载器先从缓存中找,不存在,才去加载,存在直接使用,这也是为啥修改某个类后,需要重启jvm才能失效的原因。

查找一个类的位置

 

 

类加载_第2张图片

你可能感兴趣的:(java,类加载)