没看清打开百度知道的类加载的5个过程过程有没有关系?

手把手写代码:三小时急速入门springboot—企业级微博项目实战--->

      当程序主动使用某个类时如果该类还未被类加载的5个过程到内存中,则JVM会通过类加载的5个过程、连接、初始化3个步骤来对该类进行初始化如果没有意外,JVM将会连续完成3个步骤所以有时也把这个3个步骤统称为类类加载的5个过程或类初始化。

    类加载嘚5个过程指的是将类的class文件读入到内存并为之创建一个java.lang.Class对象,也就是说当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象

    类的类加载的5个过程由类类加载的5个过程器完成,类类加载的5个过程器通常由JVM提供这些类类加载的5个过程器也是前面所有程序运行的基础,JVM提供的这些类类加载的5个过程器通常被称为系统类类加载的5个过程器除此之外,开发者可以通过继承ClassLoader基类来创建自己的类类加载的5个过程器

    通过使用不同的类类加载的5个过程器,可以从不同来源类加载的5个过程类的二进制数据通常有如下几种来源。

  • 从本地文件系统类加載的5个过程class文件这是前面绝大部分示例程序的类类加载的5个过程方式。
  • 从JAR包类加载的5个过程class文件这种方式也是很常见的,前面介绍JDBC编程时用到的数据库驱动类就放在JAR文件中JVM可以从JAR文件中直接类加载的5个过程该class文件。
  • 通过网络类加载的5个过程class文件
  • 把一个Java源文件动态编譯,并执行类加载的5个过程

    类类加载的5个过程器通常无须等到“首次使用”该类时才类加载的5个过程该类,Java虚拟机规范允许系统预先类加载的5个过程某些类

    当类被类加载的5个过程之后,系统为之生成一个对应的Class对象接着将会进入连接阶段,连接阶段负责把类的二进制數据合并到JRE中类连接又可分为如下3个阶段。

  1)验证:验证阶段用于检验被类加载的5个过程的类是否有正确的内部结构并和其他类协调一致。Java是相对C++语言是安全的语言例如它有C++不具有的数组越界的检查。这本身就是对自身安全的一种保护验证阶段是Java非常重要的一个阶段,它会直接的保证应用是否会被恶意入侵的一道重要的防线越是严谨的验证机制越安全。验证的目的在于确保Class文件的字节流中包含信息苻合当前虚拟机要求不会危害虚拟机自身安全。其主要包括四种验证文件格式验证,元数据验证字节码验证,符号引用验证

    文件格式验证:主要验证字节流是否符合Class文件格式规范,并且能被当前的虚拟机类加载的5个过程处理例如:主,次版本号是否在当前虚拟机處理的范围之内常量池中是否有不被支持的常量类型。指向常量的中的索引值是否存在不存在的常量或不符合类型的常量

    元数据验证:对字节码描述的信息进行语义的分析,分析是否符合java的语言语法的规范

    字节码验证:最重要的验证环节,分析数据流和控制确定语義是合法的,符合逻辑的主要的针对元数据验证后对方法体的验证。保证类方法在运行时不会有危害出现

    符号引用验证:主要是针对苻号引用转换为直接引用的时候,是会延伸到第三解析阶段主要去确定访问类型等涉及到引用的情况,主要是要保证引用一定会被访问箌不会出现类等无法访问的问题。

   2)准备:类准备阶段负责为类的静态变量分配内存并设置默认初始值。

   3)解析:将类的二进制数据中的苻号引用替换成直接引用说明一下:符号引用:符号引用是以一组符号来描述所引用的目标,符号可以是任何的字面形式的字面量只偠不会出现冲突能够定位到就行。布局和内存无关直接引用:是指向目标的指针,偏移量或者能够直接定位的句柄该引用是和内存中嘚布局有关的,并且一定类加载的5个过程进来的

    初始化是为类的静态变量赋予正确的初始值,准备阶段和初始化阶段看似有点矛盾其實是不矛盾的,如果类中有语句:private static int a = 10它的执行过程是这样的,首先字节码文件被类加载的5个过程到内存后先进行链接的验证这一步骤,驗证通过后准备阶段给a分配内存,因为变量a是static的所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说)到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10

  1. 创建类的实例,也就是new一个对象
  2. 访问某个类或接口的静态变量或者对该静态变量赋值
  3. 初始化一个类的子类(会首先初始化子类的父类)
  4. JVM启动时标明的启动类,即文件名和类名相同的那个类    

 对于一个final类型的静态变量如果该变量的值在编译时就鈳以确定下来,那么这个变量相当于“宏变量”Java编译器会在编译时直接把这个变量出现的地方替换成它的值,因此即使程序使用该静态變量也不会导致该类的初始化。反之如果final类型的静态Field的值不能在编译时确定下来,则必须等到运行时才可以确定该变量的值如果通過该类来访问它的静态变量,则会导致该类被初始化

类类加载的5个过程器负责类加载的5个过程所有的类,其为所有被载入内存中的类生荿一个java.lang.Class实例对象一旦一个类被类加载的5个过程如JVM中,同一个类就不会被再次载入了正如一个对象有一个唯一的标识一样,一个载入JVM的類也有一个唯一的标识在Java中,一个类用其全限定类名(包括包名和类名)作为标识;但在JVM中一个类用其全限定类名和其类类加载的5个過程器作为其唯一标识。例如如果在pg的包中有一个名为Person的类,被类类加载的5个过程器ClassLoader的实例kl负责类加载的5个过程则该Person类对应的Class对象在JVMΦ表示为(Person.pg.kl)。这意味着两个类类加载的5个过程器类加载的5个过程的同名类:(Person.pg.kl)和(Person.pg.kl2)是不同的、它们所类加载的5个过程的类也是完全不同、互不兼容的

   JVM预定义有三种类类加载的5个过程器,当一个 JVM启动的时候Java开始使用如下三种类类加载的5个过程器:

java.lang.ClassLoader(负责类加载的5个过程$JAVA_HOMEΦjre/lib/rt.jar里所有的class,由C++实现不是ClassLoader子类)。由于引导类类加载的5个过程器涉及到虚拟机本地实现细节开发者无法直接获取到启动类类加载的5个過程器的引用,所以不允许直接通过引用进行操作

下面程序可以获得根类类加载的5个过程器所类加载的5个过程的核心类库,并会看到本机咹装的Java环境变量指定的jdk中提供的核心jar包路径:

 
 



loader):被称为系统(也称为应用)类类加载的5个过程器,它负责在JVM启动时类加载的5个过程来自Java命令的-classpath选项、java.class.path系统属性或者CLASSPATH换将变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类类加载的5个过程器如果没有特别指萣,则用户自定义的类类加载的5个过程器都以此类类加载的5个过程器作为父类加载的5个过程器由Java语言实现,父类类加载的5个过程器为ExtClassLoader
類类加载的5个过程器类加载的5个过程Class大致要经过如下8个步骤:
  1. 检测此Class是否载入过,即在缓冲区中是否有此Class如果有直接进入第8步,否则进叺第2步
  2. 如果没有父类类加载的5个过程器,则要么Parent是根类类加载的5个过程器要么本身就是根类类加载的5个过程器,则跳到第4步如果父類类加载的5个过程器存在,则进入第3步
  3. 请求使用父类类加载的5个过程器去载入目标类,如果载入成功则跳至第8步否则接着执行第5步。
  4. 請求使用根类类加载的5个过程器去载入目标类如果载入成功则跳至第8步,否则跳至第7步
  5. 当前类类加载的5个过程器尝试寻找Class文件,如果找到则执行第6步如果找不到则执行第7步。
  6. 从文件中载入Class成功后跳至第8步。
 
 
1.JVM的类类加载的5个过程机制主要有如下3种
  • 全盘负责:所谓全盤负责,就是当一个类类加载的5个过程器负责类加载的5个过程某个Class时该Class所依赖和引用其他Class也将由该类类加载的5个过程器负责载入,除非顯示使用另外一个类类加载的5个过程器来载入
  • 双亲委派:所谓的双亲委派,则是先让父类类加载的5个过程器试图类加载的5个过程该Class只囿在父类类加载的5个过程器无法类加载的5个过程该类时才尝试从自己的类路径中类加载的5个过程该类。通俗的讲就是某个特定的类类加載的5个过程器在接到类加载的5个过程类的请求时,首先将类加载的5个过程任务委托给父类加载的5个过程器依次递归,如果父类加载的5个過程器可以完成类类加载的5个过程任务就成功返回;只有父类加载的5个过程器无法完成此类加载的5个过程任务时,才自己去类加载的5个過程
  • 缓存机制。缓存机制将会保证所有类加载的5个过程过的Class都会被缓存当程序中需要使用某个Class时,类类加载的5个过程器先从缓存区中搜寻该Class只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据并将其转换成Class对象,存入缓冲区中这就是为很么修改叻Class后,必须重新启动JVM程序所做的修改才会生效的原因。
 
2.这里说明一下双亲委派机制:

双亲委派机制其工作原理的是,如果一个类类加載的5个过程器收到了类类加载的5个过程请求它并不会自己先去类加载的5个过程,而是把这个请求委托给父类的类加载的5个过程器去执行如果父类类加载的5个过程器还存在其父类类加载的5个过程器,则进一步向上委托依次递归,请求最终将到达顶层的启动类类加载的5个過程器如果父类类加载的5个过程器可以完成类类加载的5个过程任务,就成功返回倘若父类类加载的5个过程器无法完成此类加载的5个过程任务,子类加载的5个过程器才会尝试自己去类加载的5个过程这就是双亲委派模式,即每个儿子都很懒每次有活就丢给父亲去干,直箌父亲说这件事我也干不了时儿子自己才想办法去完成。
双亲委派机制的优势:采用双亲委派模式的是好处是Java类随着它的类类加载的5个過程器一起具备了一种带有优先级的层次关系通过这种层级关可以避免类的重复类加载的5个过程,当父亲已经类加载的5个过程了该类时就没有必要子ClassLoader再类加载的5个过程一次。其次是考虑到安全因素java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer的类通過双亲委托模式传递到启动类类加载的5个过程器,而启动类类加载的5个过程器在核心Java API发现这个名字的类发现该类已被类加载的5个过程,並不会重新类加载的5个过程网络传递的过来的java.lang.Integer而直接返回已类加载的5个过程过的Integer.class,这样便可以防止核心API库被随意篡改

你是否真的理解Java的类类加载的5个過程机制点进文章的盆友不如先来做一道非常常见的面试题,如果你能做出来可能你早已掌握并理解了Java的类类加载的5个过程机制,若結果出乎你的意料那就很有必要来了解了解Java的类类加载的5个过程机制了。代码如下

加油吧原力计划升级版来啦!2019的年终,我们为您准備了一份流量盛宴!即日起只要参与原力计划,并且文章符合要求就可以得到流量+现金的扶持哦!

好苦恼不知道怎么才能好... 好苦惱,不知道怎么才能好

我觉得你可以考虑一2113下施博士你的洗面奶够你平时用的5261护肤品的问4102题。如果你是一直都长痘的话那可1653能跟你的洗面奶护肤品关系不大。但是如果你是就近段时间才开始一直长痘的这种的话,你可能需要考虑一下是否你的洗面奶含有致痘成分是否伱的护肤品水乳霜董不适合你使用或者的防晒等我也不是你使用。然后你说否说化妆呢如果化妆的话,可能是你卸妆没有卸干净建議要转让一个卸妆力度更强的卸妆油。总之要考虑到方向问题有很多也有可能你就是油性肤质容易长痘痘奇这个的话就建议你去医院桥裏了,因为自己是没有办法调理的

你对这个回答的评价是?


可能是自己体质的问题建议去看医生,医生还是专业些不用自己瞎想是什么原因。

你对这个回答的评价是

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

我要回帖

更多关于 加载过程 的文章

 

随机推荐