类加载器
来源:互联网 发布:世界上封锁网络的国家 编辑:程序博客网 时间:2024/05/17 21:51
看了王森的《JAVA深度历险》,做了一个简单的学习笔记。
1. JAVA类装载器在装载类的时候是按需加载的,只有当一个类要使用(使用new 关键字来实例化一个类)的时候,类加载器才会加载这 个类并初始化。
类Main:
类A:
类B:
执行:java -varbose:class Main
执行结果:
E:\DEV>java -verbose:class Main
[Opened C:\Program Files\Java\jre1.5.0_11\lib\rt.jar] (类装载器会首先加载rt.jar加载基础类)
.
.
[Loaded Main from file:/E:/DEV/] (类装载器载入相应类并初始化)
[Loaded A from file:/E:/DEV/]
Using Class A
[Loaded B from file:/E:/DEV/]
Using Class B
2. 让JAVA程序具有动态性
使用显式方式来实现动态性,我们需要自己动手处理类载入时的细节部分。
两种方法:
|
+-- 隐式的 : 使用new关键字让类加载器按需求载入所需的类
|
+-- 显式的 :
|
+-- 由 java.lang.Class的forName()方法加载
|
+-- 由 java.lang.ClassLoader的loadClass()方法加载
(1) 使用Class.forName()
Class.forName()方法具有两个重载的方法:
+- public static Class forName(String className)
|
+- public static Class forName(String className, boolean initialize,ClassLoader loader)
参数说明:
className - 所需类的完全限定名
initialize - 是否必须初始化类(静态代码块的初始化)
loader - 用于加载类的类加载器
调用只有一个参数的forName()方法等效于 Class.forName(className, true, loader)。
这两个方法,最后都要连接到原生方法forName0(),其定义如下:
private static native Class forName0(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException;
只有一个参数的forName()方法,最后调用的是:
forName0(className, true, ClassLoader.getCallerClassLoader());
而三个参数的forName(),最后调用的是:
forName0(name, initialize, loader);
所以,不管使用的是new 來实例化某个类、或是使用只有一个参数的Class.forName()方法,内部都隐含了“载入类 + 运行静态代码块”的步骤。而使用具有三个参数的Class.forName()方法时,如果第二个参数为false,那么类加载器只会加载类,而不会初始化静态代码块,只有当实例化这个类的时候,静态代码块才会被初始化,静态代码块是在类第一次实例化的时候才初始化的。
(2) 直接使用类加载器
+— 获得对象所属的类 : getClass()方法
|
+— 获得该类的类加载器 : getClassLoader()方法
3 类加载器的层次
1. JAVA类装载器在装载类的时候是按需加载的,只有当一个类要使用(使用new 关键字来实例化一个类)的时候,类加载器才会加载这 个类并初始化。
类Main:
java 代码
- public class Main {
- public static void main(String[] args) {
- A a = new A();
- a.print();
- B b = new B();
- b.print();
- }
- }
类A:
java 代码
- public class A {
- public void print() {
- System.out.println("Using Class A");
- }
- }
类B:
java 代码
- public class B {
- public void print() {
- System.out.println("Using Class B");
- }
- }
执行:java -varbose:class Main
执行结果:
E:\DEV>java -verbose:class Main
[Opened C:\Program Files\Java\jre1.5.0_11\lib\rt.jar] (类装载器会首先加载rt.jar加载基础类)
.
.
[Loaded Main from file:/E:/DEV/] (类装载器载入相应类并初始化)
[Loaded A from file:/E:/DEV/]
Using Class A
[Loaded B from file:/E:/DEV/]
Using Class B
2. 让JAVA程序具有动态性
使用显式方式来实现动态性,我们需要自己动手处理类载入时的细节部分。
两种方法:
|
+-- 隐式的 : 使用new关键字让类加载器按需求载入所需的类
|
+-- 显式的 :
|
+-- 由 java.lang.Class的forName()方法加载
|
+-- 由 java.lang.ClassLoader的loadClass()方法加载
(1) 使用Class.forName()
Class.forName()方法具有两个重载的方法:
+- public static Class forName(String className)
|
+- public static Class forName(String className, boolean initialize,ClassLoader loader)
参数说明:
className - 所需类的完全限定名
initialize - 是否必须初始化类(静态代码块的初始化)
loader - 用于加载类的类加载器
调用只有一个参数的forName()方法等效于 Class.forName(className, true, loader)。
这两个方法,最后都要连接到原生方法forName0(),其定义如下:
private static native Class forName0(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException;
只有一个参数的forName()方法,最后调用的是:
forName0(className, true, ClassLoader.getCallerClassLoader());
而三个参数的forName(),最后调用的是:
forName0(name, initialize, loader);
所以,不管使用的是new 來实例化某个类、或是使用只有一个参数的Class.forName()方法,内部都隐含了“载入类 + 运行静态代码块”的步骤。而使用具有三个参数的Class.forName()方法时,如果第二个参数为false,那么类加载器只会加载类,而不会初始化静态代码块,只有当实例化这个类的时候,静态代码块才会被初始化,静态代码块是在类第一次实例化的时候才初始化的。
(2) 直接使用类加载器
+— 获得对象所属的类 : getClass()方法
|
+— 获得该类的类加载器 : getClassLoader()方法
java 代码
- public class Main3 {
- public static void main(String[] args) throws Exception {
- Main3 main3 = new Main3();
- System.out.println("准备载入类");
- ClassLoader loader = main3.getClass().getClassLoader();
- Class clazzA = loader.loadClass(args[0]);
- System.out.println("实例化类A");
- A o1 = (A) clazzA.newInstance();
- }
- }
3 类加载器的层次
- 加载、类加载、类加载器
- 类加载机制及类加载器加载Class流程
- 类加载器---类加载器简介
- Java类加载器加载类顺序
- 类加载器---类加载机制
- Java类加载器加载类顺序
- Java类加载器加载类顺序
- Java类加载器加载类顺序
- 类加载器和类加载机制
- 使用类加载器加载配置文件
- 用类加载器加载配置文件
- 用类加载器加载配置文件
- 类加载器的加载机制
- 用java类加载器加载资源
- 扩展类加载器的加载问题
- java类加载器的加载顺序
- 使用类加载器加载配置文件
- Java 类加载器以及加载机制
- boost regex正则区配 IP 地址
- 传智播客版android手机斗地主_成都Java培训_传智播客
- android 自旋锁 spin_lock
- 使用stringstream对象简化类型转换
- Func,Action 的介绍及其用法
- 类加载器
- java中读写锁的实现及使用读写锁简单实现缓存系统的实例
- 在c#项目中调用及调试c++写的dll
- Linux下用Apt-get 安装Mysql
- xcode联机测试
- VS2008编译Qt4.5
- SAP中与薪资计算有关的常用函数及表项
- web.xml 中的listener、 filter、servlet 加载顺序及其详解
- 这小子会如斯的厉害