• JVM_类加载机制


    java文件想要被jvm识别首先要被转化成class文件,class文件是一个16进制的文件

    当java文件转化成class文件后就会出现一个问题,是jvm主动获取这个class文件还是class文件自己进入jvm。 

    jvm就出现了类加载机制。 

    类加载机制就是jvm主动去获取文件夹中的类。

    主动获取的条件:

    1.外部调用这个类,读取内部的final和static变量

    2.new一个对象

    3.调用静态方法

    类加载机制的步骤

    Loading , linking, initialzing

    (1) 装载 loading :各个类装载器扫描自己负责的文件夹下(创建class常量池和运行时常量池)

    类装载器

       启动类加载器(Bootstrap classLoader):又称为引导类加载器,由C++编写,无法通过程序得到。主要负责加载JAVA中的一些核心类库,主要是位于<JAVA_HOME>/lib/rt.jar中。

         拓展类加载器(Extension classLoader):主要加载JAVA中的一些拓展类,位于<JAVA_HOME>/lib/ext中,是启动类加载器的子类。

         应用类加载器(System classLoader):    又称为系统类加载器,主要用于加载CLASSPATH路径下我们自己写的类,是拓展类加载器的子类。


    但是又会出现一个问题,当各自文件夹下面都有一个 java.lang.String 文件时。这个类加载器会如何加载。

    双亲委派

    三个类加载器实际上属于继承关系,

    classLoader(){

    //先交给自己的父类来扫描,如果扫描到了这个类,装载然后结束

    //父类没有扫描到则交给子类来扫描,扫描到了装载然后结束

    //如果没有扫描到,抛出 异常

    }

    想要破环这个双亲委派,简单的就是重写这个classLoader方法。

    (2)链接 linking:准备:分配方法区空间,主要是类变量(static修饰的)并设置初始值。(创建了全局字符串池)

            检查:确保被加载类的正确性

              解析:将符号引用转化为直接引用

    (3)初始化 init : 类变量的赋值和static代码块的执行。

                         子类的初始化是从父类开始的,父类的静态代码块和类变量赋值--->子类的静态代码块和类变量赋值

      类会在外部主动调用的时候进行初始化步骤:

      1. 类的实例化(new,反射等)

      2.    调用类的静态方法

      3.    调用类或者某个接口的静态变量

      4.    子类进行了初始化

      5.    调用反射,Class.forName()和java.reject包里面的方法

      6.    虚拟机启动某个标注为启动类的类(mian方法)

    问题:

    1.因为实例化一个子类的时候会先执行父类的构造方法,所以是不是也相当于实例化了一个父类对象?

    实例化对象的时候确实会执行一次构造方法,但是执行构造方法只是为了为变量赋值,并不能说实例化了对象。

    2.加载后的类会放在哪里?

    没有实例化的class会被ClassLoader在堆里面创建一个代表这个类的class对象作为访问方法区的入口。

  • 相关阅读:
    【Linux】命令——基本命令
    正则表达式
    Letex
    Markdown
    文本编辑器Vim
    【Linux】集群
    【Linux】软件安装
    共线性synteny
    windows触控手势
    【Linux】bin结尾的安装包
  • 原文地址:https://www.cnblogs.com/frank9571/p/12370944.html
Copyright © 2020-2023  润新知