虚拟机如何加载类

1024冲冲冲

虚拟机如何加载类

规范化的字节码要加载到虚拟机之中,需要经过特定的步骤。

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

Java里类型的加载、连接和初始化过程都是在程序运行期间完成的,这为Java应用程序提供了高度的灵活性,Java里天生可以动态扩展。

类加载的时机

该流程中,加载、验证、准备、初始化和卸载这5个阶段顺序固定,解析阶段是动态的,与Java动态绑定符合。

当类被使用时,且需要初始化时才会初始化。主要有new操作,反射,初始化类后该类的父类初始化,虚拟机启动主类,动态语言支持等,在类没有被初始化的时候将初始化一个类到内存中。

接口的父接口只有在用到的时候才会进行初始化操作。

类加载的三个步骤

  1. 通过一个类的全限定名类获取定义此类的二进制字节流(字节码文件)
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

可以通过重写loadClass()方法制作一个滴定仪的类加载器。

类加载器

通过一个类的全限定名来获取描述此类的二进制字节流

类加载器可以不止被用来加载类,在判断类的类型时也在发挥重要作用。

双亲委派模型

目的:起到沙箱机制,保护关键类不能被改写,可扩展性。

实现原理:通过不同的类加载器间的相互合作达到目标

从Java虚拟机的角度,只存在两种不同的类加载器:

  • 启动类加载器(Bootstrap ClassLoader,使用C++语言实现,是虚拟机自身的一部分);
  • 所有其他的类加载器,这些加载器使用Java实现,独立于虚拟机外部,并且全部继承抽象类java.lang.ClassLoader

从Java开发者的角度有4种系统提供的类加载器

  • 启动类加载器,Bootstrap ClassLoader,负责将存放在<Java_HOME>\lib目录中的,用户编写自定义的类加载器时,如果需要把加载请求委派给引导类加载器,直接使用null代替即可。
  • 扩展类加载器,Extension ClassLoader,由sun.misc.Launcher$ExtClassLoader实现,负责加载<JAVA_HOME>\lib\ext目录中的类
  • 应用程序类加载器,Application ClassLoader,由sun.misc.Lancher$AppClassLoader实现。负责加载用户路径上所指定的类库,开发者可以直接使用该类加载器。应用程序中没有自定义类加载器,一般情况下默认为该类加载器。
  • 用户自定类加载器,继承一个类加载器,重写loadClass()方法

img

猜你喜欢

转载自blog.csdn.net/weixin_44494373/article/details/109255728