`

java类加载的过程

    博客分类:
  • JVM
JVM 
阅读更多

一、类加载器

       类加载器是JVM执行类加载机制的前提,其主要任务为根据一个类的全限定名来读取 此类的二进制字节流到JVM内部,然后转换为一个与目标类对应的java.lang.Class对象实例;

        类加载器:ClassLoader

        ①ClassLoader除了将Class加载到JVM之外,还有一个重要的作用就是审查每个类应该有谁加载,它是一种父优先的等级加载机制;

        ②ClassLoader还有一个重要的作用就是将Class字节码重新解析成JVM统一要求的对象格式;

        ClassLoader主要包括defineClass(),findClass(),loadClass(),resolveClass()几个方法:

        defineClass方法 的主要作用是将byte 字节流解析成JVM能够识别的class对象,这个方法意味着 我们不仅仅可以通过class文件去实例化对象,还可以其他方式实例化对象,例如我们通过网络接收到一个类的字节码;defineClass的代码如下:

 protected final Class<?> defineClass(String name, byte[] b, int off, int len,
                                         ProtectionDomain protectionDomain)
        throws ClassFormatError
    {
        protectionDomain = preDefineClass(name, protectionDomain);
        String source = defineClassSourceLocation(protectionDomain);
        Class<?> c = defineClass1(name, b, off, len, protectionDomain, source);
        postDefineClass(c, protectionDomain);
        return c;
    }


    protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
                                         ProtectionDomain protectionDomain)
        throws ClassFormatError
    {
        int len = b.remaining();

        // Use byte[] if not a direct ByteBufer:
        if (!b.isDirect()) {
            if (b.hasArray()) {
                return defineClass(name, b.array(),
                                   b.position() + b.arrayOffset(), len,
                                   protectionDomain);
            } else {
                // no array, or read-only array
                byte[] tb = new byte[len];
                b.get(tb);  // get bytes out of byte buffer.
                return defineClass(name, tb, 0, len, protectionDomain);
            }
        }

        protectionDomain = preDefineClass(name, protectionDomain);
        String source = defineClassSourceLocation(protectionDomain);
        Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source);
        postDefineClass(c, protectionDomain);
        return c;
    }

        defineClass()通常是和findClass()一起使用,我们可以通过覆盖父类中的findClass 方法来实现类的加载规则,从而取得加载类的字节码,然后调用defineClass方法生成的Class对象;

 

二、如何加载Class文件

        ClassLoader加载一个class文件到 JVM中,需要经过以下的步骤:

        .class文件----->findClass------>验证、准备、解析----->初始化------>卸载

        即:加载---->连接----->初始化---->卸载

       ①找到.class文件并把这个文件包含的字节码加载到内存中;

       ②字节码验证、Class类数据结构分析及相应的内存分配和最后符号表的链接;

       ③类中静态属性和初始化赋值,以及静态块的执行;

        加载字节码到内存:

        抽象类ClassLoader通过findClass找到指定类并把他的 字节码加载到内存需要的子类中去实现;

        验证:

        验证阶段JVM所执行的一系列验证大概分为:格式验证、语义验证、操作验证、符号引用验证;

        格式验证的主要任务就是检查当前正在加载的字节码文件是否符合JVM规范 ,是否是一个有效的字节码文件,格式验证的主要任务是检查当前正在加载的字节码文件中的前四个字节是否是0xCAFEBABE;

        语义验证:验证字节码信息是否符合java语法规范;

        操作验证:JVM会对类型的方法执行验证,以确保一个类的方法在执行时,不会对JVM产生不良影响不会因此导致JVM的进程出现崩溃;

        符号引用验证:对常量池中的各种符号引用执行验证;

        准备阶段:

        对存放在方法区 中类数据信息的类变量执行初始化,这里所执行 的初始化操作并非是指类加载阶段中的初始化操作,这里仅仅是为类中的所有静态变量分配内存空间,并为其设置一个初始值,而非用户手动执行赋值操作;

        解析阶段:

        主要任务是将字节码常量池中的符号引用全部转换为直接引用,包括类、接口、方法和字段的符号引用。

        初始化:

        在 这个阶段中,JVM会将一个类中所有被static关键字标示的代码统统执行一遍,如果执行的是静态常量,那么用户将会使用用户指定的值覆盖掉之前在准备阶段中JVM为其设置的初始值,如果程序中并没有为静态变量显式指定赋值操作,那么 所持有的值仍然是之前的初始值;反之如果执行的是static代码块,那么在初始化阶段中,JVM就将会执行static代码块中定义的所有操作;

分享到:
评论

相关推荐

    java类加载过程详解.doc

    Java 类加载过程是Java虚拟机(JVM)在运行时动态加载类的机制,它涉及类的生命周期中的几个关键步骤,包括装载、连接、初始化和卸载。下面将详细阐述这些过程。 1. 装载 装载阶段是类加载的起始点,主要分为三个...

    java类加载器

    #### 二、类加载过程 类加载过程主要包括三个步骤: 1. **加载**:通过类的全限定名找到该类的二进制字节流。 2. **连接**: - **验证**:确保加载的类文件符合JVM规范,包括字节流文件的格式正确性、元数据的...

    Java类加载基本过程详细介绍

    Java类加载过程是Java应用程序启动的关键步骤,它涉及到类的加载、链接以及初始化。下面将详细阐述这些步骤。 1. **加载**: 加载阶段是类加载过程的第一步,它的任务是找到类的二进制字节流,并将其加载到Java...

    Java类加载内幕详细讲解

    #### 五、类加载过程详解 类加载的过程主要分为三个阶段:加载(Loading)、连接(Linking)和初始化(Initialization)。 1. **加载**(Loading): - 类加载器查找并加载类的二进制流。 - 创建`java.lang....

    Java类加载器.pdf

    例如,在提供的代码示例中,`Main`类通过`new A()`和`new B()`语句分别实例化了`A`和`B`类,这触发了类加载器对这两个类的加载过程。 #### 类加载器的层次结构 Java中的类加载器通常按照以下层次结构组织: 1. **...

    Java类加载器原理

    Java 类加载器原理 Java 类加载器是Java虚拟机...类加载器的机制保证了Java的类加载过程是有序且安全的,同时也支持了Java的动态加载和模块化特性。在自定义类加载器时,需要遵循这些规则,以便正确地扩展JVM的功能。

    深入研究Java类加载机制 深入研究Java类加载机制

    Java类的加载过程可以分为以下几个步骤: 1. **加载**(Loading):找到并读取class文件的数据,将其转换成字节流,再将这些数据转化成对应的二进制数据加载到内存中。 2. **链接**(Linking): - **验证**...

    springboot+java类热加载

    **动态编译**:在热加载过程中,可能会涉及到对源代码的动态编译。`ClassUtil.java`可能包含了一些辅助方法,用于在运行时编译修改后的Java源码,然后由类加载器加载到JVM中。Java的`javac`工具或第三方库如Apache ...

    Java类加载及SPI机制.zip

    Java类加载过程分为三个主要阶段:加载、链接和初始化。在加载阶段,类加载器会找到对应的.class文件并创建一个二进制数据流。链接阶段则包括验证、准备和解析三个子步骤,验证确保.class文件的正确性,准备阶段为类...

    第23讲请介绍类加载过程,什么是双亲委派模型1

    Java 类加载过程是Java程序运行时的关键环节,它涉及到如何将类的字节码加载到JVM中并准备执行。整个过程可以分为五个主要步骤:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)和...

    自定义Java类加载器

    在Java中,类加载过程分为加载、验证、准备、解析和初始化五个阶段。 首先,让我们了解Java中的默认类加载器体系: 1. **Bootstrap ClassLoader**:这是最基础的类加载器,由JVM自身实现,通常用于加载`&lt;JAVA_HOME...

    java 类加载器 加密

    Java 类加载器是Java运行时环境的一个重要组成部分,它的主要职责是将编译后的字节码(.class文件)加载到JVM中,使得程序能够运行。类加载器的机制保证了类的唯一性,同时也提供了灵活性,允许我们自定义加载逻辑。...

    深入理解Java 类加载全过程

    加载阶段是类加载过程的起点,它涉及以下步骤: - **定位类文件**:JVM根据类的全限定名(包名+类名)在类路径(classpath)中找到对应的.class文件。 - **读取字节流**:将.class文件中的二进制数据读入内存,并...

    java类加载器-tomcat中的类加载器

    Java 类加载器是Java虚拟机(JVM)的核心组成部分,它负责将...它涉及到类的查找、加载、初始化等过程,以及如何通过调整类加载器配置来优化应用性能和安全性。深入研究这些概念,能够让你在处理类加载问题时游刃有余。

    Java虚拟机----类的加载过程.docx

    Java虚拟机(JVM)的类加载过程是Java程序运行的基础,它涉及到类加载器、类的生命周期和一系列复杂的步骤。在这个过程中,类加载器主要任务是根据类的全限定名加载二进制字节流并转化为`java.lang.Class`对象。整个...

    Java类加载原理解析

    当遇到`java.lang.ClassNotFoundException`异常时,通常是因为类加载过程出现了问题。了解类加载机制对于解决这类问题至关重要,同时也有助于深入理解Java虚拟机(JVM)的工作原理。 Java 类加载机制主要由类加载器...

    java类加载原理分析

    Java 类加载原理是Java运行时环境中的核心机制之一,它涉及到类的生命周期、类加载器的层次结构以及类的查找和加载过程。了解这一机制对于深入理解Java平台的工作原理至关重要,尤其是在开发自定义类加载器或者处理...

    JAVA类加载机制与动态代理

    值得注意的是,接口的加载过程与类加载过程稍有不同。接口在初始化时,并不要求其父接口全部都完成了初始化,只有在真正使用到父接口的时候(如引用接口中定义的常量)才会初始化。 ##### 1.2 类加载的过程 类加载...

Global site tag (gtag.js) - Google Analytics