类加载的方式有2种。
l
显示类加载
ClassLoader.loadClass()(使用指定的Classloader进行装载)
Class.forName()(使用当前类的Caller Classloader进行装载)
l
隐示类加载(发生在由于引用、实例化或继承导致需要装载类的时候。隐式类装载是在幕后启动的,JVM会解析必要的引用并装载类。)
Classloader可能先显式地装载一个类,然后再隐式地装载它引用的其它类。
从类装载方式的描述中我们可以看到,
只有在显式的调用方法或者实例化、引用、继承一个类时,类才真正被装载
。由此,我们可以知道,import并不会导致类装载,以及,在一个类实例化之前,调用它的静态方法,会导致这个类和它的父类、实现的接口和相关的静态成员的类会被装载,而它的成员变量的类却不会被装载
ClassLoader中有个ClassLoader类型的parent的属性,表示需要loadClass的时候先找parent加载。
这跟职责链模式有点类似,职责链是自己处理不了就交给下一个处理器处理。而在ClassLoader中,是先找到自己的parent加载类,递归地找到最高层次的parent,如果不成功,再让本ClassLoader进行类加载。如果parent为null,则认为是JVM中的BootStrapClassLoader。
在JVM启动后,类的加载方式有2种,一种是预先加入(pre-loading),另外一种是按需载入(load-on-demand)。
如图,在JVM启动以后首先启动BootStrapClassLoader,BootStrapClassLoader开始加载核心API类,在加载sun.misc下的Launcher.java以后加载2个内部类。
第一个是ExtClassLoader,负责把Java的扩展库载入。同时将ExtClassLoader的parent设为null,也就是BootStrapClassLoader。
第二个是AppClassLoader,负责把CLASSPATH路径下的类库和用户自定义类加载到内存中。其parent是ExtClassLoader。
类的加载器可以用Class.getClassLoader()方法来获得。如下示例:
System.out.println(App.class.getClassLoader());//App是自定义类
System.out.println(String.class.getClassLoader());
返回结果是:
sun.misc.Launcher$AppClassLoader@19821f
null
数组类的Class对象不是由类加载器创建的,而是由Java运行时根据需要自动创建。如果是基本数据类型,则没有类加载器。
自定义的ClassLoader可以继承URLClassLoader或ClassLoader。当继承ClassLoader重写findClass()方法,parent会相应是AppClassLoader-->ExtClassLoader-->BootStrapClassLoader。
只有在实例化一个类的时候才会被ClassLoader载入,仅仅申明并不会。
ClassLoader 中最关键的loadClass()源码:
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
可以看见第一步是先查找该类是否已经加载,如果未加载,查看parent是否为空,不空的话就交给parent处理,空的话就交给 findBootstrapClassOrNull()方法,该方法让BootStrapClassLoader加载类。如果从parent那里加载失败 (抛出异常了),那么就让自己加载类(调用本类被继承的方法findClass())。之后判断resolve,如果为真就
连接。
说到连接,参考《深入Java虚拟机》。
类装载器子系统除了要定位和导入二进制文件外,还必须确认验证被导入类的正确性,为类变量分配并初始化内存。这些动作的顺序是:1)装载;2)连接:a.验证;b.准备;c.初始化;3)初始化。
装载就是查找并将二进制数据装到虚拟机中。
连接开始时执行验证,验证后就准备,准备的过程是为类变量(静态变量)分配内存并将其初始化为默认值。解析这一步是可选的,是将类型中的符号引用转换为直接引用。之后进行初始化,这时候把类变量初始化为正确的值(有进行引用赋值的情况下)。
分享到:
相关推荐
在Java虚拟机(JVM)中,类加载器(ClassLoader)是至关重要的组成部分,它负责查找和加载类的字节码文件。理解ClassLoader的工作机制对于深入掌握Java应用程序的运行至关重要。这里我们将详细讨论ClassLoader的运行...
《深入理解ClassLoader》 在Java世界中,ClassLoader是运行时加载类的核心机制,它负责将类的.class文件加载到JVM中,使得程序能够运行。本文将深入剖析ClassLoader的工作原理,以及其在实际开发中的应用。 一、...
Java ClassLoader是Java运行时系统的关键但经常被忽视的组件,负责在运行时查找和加载类文件。通过创建自定义ClassLoader,你可以定制JVM,使类文件的引入方式完全重新定义,这提供了很多实用和有趣的可能。这篇教程...
### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...
在Java中,Classloader是加载类的关键组件,它负责查找、加载和初始化字节码文件。自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们...
Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...
《深入理解ClassLoader工作机制》 Java虚拟机(JVM)中的ClassLoader是负责加载类到内存中的核心组件。它不仅承担着将字节码转换为可执行对象的重任,还参与了类生命周期的各个阶段,包括加载、验证、准备、解析、...
首先,ClassLoader可以分为三种基本类型:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。Bootstrap ClassLoader是JVM启动时的第一个ClassLoader,负责加载JDK的`<JAVA_HOME>\lib`目录下...
《ClassLoader详解》 Java应用程序的运行离不开类的加载,而ClassLoader正是这个过程的关键角色。它负责将类的字节码加载到Java虚拟机(JVM)中并转换为可执行的Java对象。深入理解ClassLoader的工作原理对于优化...
Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...
Java ClassLoader是一个核心的Java运行时组件,负责加载类到Java虚拟机(JVM)中。它是Java平台的独特特性,因为它允许动态加载类,增强了软件的可扩展性和灵活性。这篇博文(虽然链接不可用)可能深入探讨了...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中。自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热...
破解java加密的ClassLoader.java,在classloader植入破解代码
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中执行。本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中执行。这篇测试主要探讨了ClassLoader的工作原理及其在实际应用中的使用。通过阅读给出的博文链接,我们可以深入理解...