类的加载并不导致类的初始化,class.forName(),其实是有参数来设定是否对类进行初始化的,当对应参数设为true时,是对包含加载和初始化两个部分的。
当一个Java类第一次被真正使用到的时候,JVM会进行该类的初始化操作。初始化过程的主要操作是执行静态代码块和初始化静态域。Java类和接口的初始化只有在特定的时机才会发生,这些时机包括:
创建一个Java类的实例。如
MyClass obj = new MyClass()
调用一个Java类中的静态方法。如
MyClass.sayHello()
给Java类或接口中声明的静态域赋值。如
MyClass.value = 10
访问Java类或接口中声明的静态域,并且该域不是常值变量。如
int value = MyClass.value
在顶层Java类中执行assert语句。
这里需要注意类的初始化和实例化完全两个概念,类的初始化只和静态相关,而类的实例化则是在创建实例对象时才会发生。当实例化时才会去对非静态域进行初始化(这个初始化是和创建的实例对象相关联的)以及调用构造方法。构造方法在初始化成员变量之后进行也是有原因的,如果在构造方法里给某个成员变量赋值了,那么成员变量还没有初始化如何能赋值。
ClassLoader相关
java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 java.lang.Class类的一个实例。
java.lang.ClassLoader中提供的方法:
defineClass():这个方法用来完成从Java字节代码的字节数组到java.lang.Class的转换。这个方法是不能被覆写的,一般是用原生代码来实现的。
findLoadedClass():这个方法用来根据名称查找已经加载过的Java类。一个类加载器不会重复加载同一名称的类。
findClass():这个方法用来根据名称查找并加载Java类。
loadClass():这个方法用来根据名称加载Java类。
resolveClass():这个方法用来链接一个Java类。
这里比较 容易混淆的是findClass()方法和loadClass()方法的作用。在Java类的链接过程中,会需要对Java类进行解析,而解析可能会导致当前Java类所引用的其它Java类被加载。在这个时候,JVM就是通过调用当前类的定义类加载器的loadClass()方法来加载其它类的。findClass()方法则是应用创建的类加载器的扩展点。应用自己的类加载器应该覆写findClass()方法来添加自定义的类加载逻辑。 loadClass()方法的默认实现会负责调用findClass()方法
一般来说,自己开发的类加载器只需要覆写 findClass(String name)方法即可。java.lang.ClassLoader类的方法 loadClass()封装了前面提到的代理模式的实现。该方法会首先调用 findLoadedClass()方法来检查该类是否已经被加载过;如果没有加载过的话,会调用父类加载器的 loadClass()方法来尝试加载该类;如果父类加载器无法加载该类的话,就调用 findClass()方法来查找该类。
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}
else {
return defineClass(name, classData, 0, classData.length);
}
}
http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
http://www.infoq.com/cn/articles/cf-Java-class-loader
分享到:
相关推荐
首先,我们来看类的初始化过程,也称为类加载与初始化。当Java虚拟机(JVM)首次遇到某个类的实例或者静态变量,或者当类的静态方法被调用时,会触发类的加载和初始化。类的初始化主要涉及到以下几个步骤: 1. 类...
标题中的“全局变量初始化导致的dll加载失败工程”是一个典型的C++编程问题,涉及到动态链接库(DLL)的加载机制以及全局变量的初始化顺序。在C++编程中,全局变量的初始化顺序是一个需要深入理解的概念,尤其是在...
静态初始化发生在程序加载时,主要针对那些可以用常量表达的初始化,例如零初始化(zero initialization)和常量初始化(const initialization)。零初始化的变量通常存放在BSS段,而常量初始化的变量则位于数据段,...
- **加载与初始化**:`Class.forName()`的主要作用是根据给定的类的全限定名(包括包名)来加载并初始化该类。如果类尚未被加载,则将其加载到JVM中;如果已经加载,则不会重复加载。这一步骤确保了驱动程序类的可用...
例如,假设我们有 2 个 bean A 和 B,B 加载的文件依赖 A 中加载的全局配置文件中的路径,所以需要 A 先于 B 初始化。此外,A 中的配置改变后也需要触发 B 的重新加载逻辑,所以 A 和 B 需要互相注入。 方案一:...
### 深入Java虚拟机加载初始化 #### Classloader的作用及意义 在深入了解Java虚拟机(JVM)的加载初始化之前,我们先明确一下`Classloader`的角色。简单地说,`Classloader`的主要职责是将编译后的`.class`文件...
java JVM 类加载-初始化 过程
这两种初始化块在创建类实例或加载类时分别扮演着不同的角色。 **静态初始化块** 静态初始化块是以`static`关键字标识的代码块,它在类被加载到Java虚拟机(JVM)时执行,且只执行一次。静态初始化块常用于设置类...
利用实验数据进行应力初始化可以提高模拟的准确性,这通常需要与应变测量结合,如应变计或声发射传感器的数据。 8. **后处理与验证**:完成模拟后,通过后处理工具可视化和分析应力分布,对比实验结果或其他计算...
6. **类初始化与类加载器**: - 类的初始化是由对应的类加载器触发的,当且仅当以下条件之一满足时: - 遇到new关键字实例化对象; - 遇到静态字段(非final)并对其进行访问; - 遇到静态方法的调用; - 使用...
`init`文件可能包含了各种构造函数的实现,展示它们如何被调用以及与初始化块交互的方式。 5. **成员变量初始化**: Java允许我们在变量声明时进行初始化。这种初始化发生在构造函数之前,因此在实例初始化块之前...
- 调用父类的静态成员变量并不会导致子类的加载与初始化,只会加载父类。 4. **接口在初始化时,并不要求其父接口全部都完成了初始化**(√); - 接口的初始化顺序是按需加载的,也就是说,只有在真正使用到...
在“MM”这个文件中,我们可以看到与内存管理相关的初始化内容。它可能包含了初始化DDR内存、配置MMU规则、设置页表等步骤。具体步骤可能如下: 1. DDR初始化:设置DDR控制器寄存器,定义内存大小、速度、时序等参数...
这意味着,即使`InitCommonControls`函数本身不执行任何操作,但它会导致链接器将程序与comctl32.dll关联,从而在运行时自动完成必要的初始化工作。 相比之下,`InitCommonControlsEx`函数允许更精细的控制,因为它...
在工业控制系统中,"设备初始化失败"是一个常见的问题,这可能由多种原因引起,例如驱动程序不兼容、系统设置错误、硬件故障或是缺少必要的组件。在本案例中,提到的“组态王设备初始化失败安装可用”指的是,当遇到...
Revit外部工具无法初始化附加模块的解决方法 大家在安装完Revit或者卸载后重装Revit时是否遇到外部工具无法初始化附加模块的问题,每次打开不停的弹出对话框,烦得要死。 无法初始化附加模块“CollaborateDB”,...
1. **加载与初始化**:当FlexViewer启动时,首先由浏览器中的Flash Player加载并管理。随后,FlexViewer会自动加载配置文件(Config.xml),根据其中的各项配置初始化系统的功能和界面。 2. **地图数据加载**:接...
2. **静态代码块与静态变量的初始化**:在类加载时,静态代码块和静态变量会被初始化,它们的执行顺序取决于它们在代码中的出现顺序,而不是它们的定义顺序。这意味着,如果一个类中包含了多个静态代码块或静态变量...