为知笔记http://a36bf370.wiz03.com/share/s/2zq_dM1mlQS52P2klg35rzwa2N_BL516Ik0O2DHUJE1jtbbE
当程序主动使用某个类时,如果该类未被加载到内存中,就会加载进内存,并为之创建一个java.lang.Class对象。类的加载由类加载器完成,JVM提供了系统类加载器,而开发者也可以通过继承ClassLoader基类来创建自己的类加载器。类加载器通常无须等到“首次使用”该类时加载该类,java虚拟机规范允许系统预先加载某些类。
通过使用不同的类加载器来加载不同来源的二进制数据
从本地文件系统加载class文件,这是前面绝大部分示例程序的类加载方式。从JAR包加载class文件。通过网络加载class文件。把一个java源文件动态编译并执行。类加载之后,系统生成一个对应的Class对象,接着将会进入连接阶段。连接阶段负责把类的二进制数据合并到JRE中。分为以下三个阶段。
验证 : 用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。准备 : 负责为类的类变量分配内存,并设置默认初始值。解析 : 将类的二进制数据中的符号引用替换成直接引用。在类的初始化阶段,虚拟机负责对进行初始化,主要就是对类变量进行初始化。
类加载器负责将.class加载到内存中,并为之生成对应的java.lang.Class对象。一旦一个类被加载到JVM中,同一个类就不会被再次加载。同一个类指全限定类名(包名和类名的统称)和类加载器相同的情况下加载的出的类。 当JVM启动时,会形成由三个类加载器组成的初始类加载器的层次结构。
Bootstrap ClassLoader: 根类加载器Extension ClassLoader : 扩展类加载器System ClassLoader : 系统类加载器被称为引导类加载器,负责加载java的核心类。可以通过执行java.exe命令时, 使用-Xbootclasspath选项或使用-D选项指定sun.boot.class.path系统属性值进行加载附加的类。该类不是java.lang.ClassLoader的子类。由JVM自身实现。
被称为扩展类加载器,负责加载JRE的扩展目录(jre/lib/ext或者由java.ext.dirs系统属性指定的目录)中的jar包的类。只需要把自己开发的类打包成JAR文件,放入到该目录下,既可以扩展核心类意外的新功能。
被称为系统类加载器,负责JVM启动时加载来自java命令的-classpath选项,java.class.path系统属性,或者CLASSPATH环境变量所制定的JAR包的类和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以类加载器作为父加载器。