Java 中 Class.forName() 的用法
一、类和 Class 对象
类是程序的一部分,每个类都有一个 class 对象。换言之,每当编写并且编译了一个新类,就会产生一个 class 对象(更恰当的说,是被保存在一个同名的 .class 文件中)。为了生成这个类的对象,运行这个程序的Java虚拟机(jvm)将使用被称为“类加载器”的子系统。
所有的类都是在对其第一次使用的时候被加载到JVM中。如当程序创建对第一个静态成员的引用时,就会加载这个类。或者使用new关键字创建新的对象的时候。因此java程序在它运行之前并非完全加载,其各个部分是在必须的时候才加载的。类加载器首先检查这个类的class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件。
Class.forName() 要求 JVM 查找并加载指定的类,作用是执行该类的静态代码段,加载了类以后还需要进行类初始化操作才能正常使用此类,类初始化操作就是执行一遍类的静态语句,包括静态变量的声明还有静态代码块。
Class类也是类的一种,与 class 关键字是不一样的。如一个编写好的类在被编译后会产生一个Class对象,其表示的是创建的类的类型信息,而且这个Class对象保存在同名 .class 的文件中(字节码文件),每个通过关键字class标识的类,在内存中有且只有一个与之对应的Class对象来描述其类型信息,无论创建多少个实例对象,其依据的都是用一个Class对象。
Java 中获取 Class 有三种方式(以 string 类为例)
1、通过对象的getClass()方法
Class<?> clazz1 = str.getClass();
2、通过类的.class属性
Class<?> clazz2 = String.class;
3、通过Class类的静态方法forName(String className)
Class<?> clazz3 = Class.forName("java.lang.String");
这里只重点理解第三种方式。
二、 Class.forName() 方法
forName(String className)
1、 初始化initialize=true
2、 总是使用当前类装载器(也就是装载执行forName()请求的类的类装载器)
3、 总是初始化这个被装载的类(当然也包括:装载、连接、初始化)
forName(String className, boolean initialize, ClassLoader loader)
1、 loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。
2、 initialize=true时,肯定连接,而且初始化了;
3、 initializ=false时,绝对不会初始化,但是可能被连接了,但是这里有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,这里也暗含着:被同一个loader所装载的,而且这个类被初始化了)
三、实例
实例一
String className = "Example";
Class c = Class.forName(className);
ExampleInterface factory = (ExampleInterface)c.newInstance();
实例二
// 获取内部窗体的唯一实例对象
private JInternalFrame getIFrame(String frameName) { //传入的字符参数为类的名称
JInternalFrame jf = null;
if (!ifs.containsKey(frameName)) { //如果映射中未存在
try { //寻找到并执行那个子窗体类
Class fClass = Class.forName("internalFrame." + frameName); //根据项目文件的路径加载对应的类
Constructor constructor = fClass.getConstructor(null); //获取类构造器
jf = (JInternalFrame) constructor.newInstance(null); //类加载机制
ifs.put(frameName, jf); //加入映射
} catch(Exception e) {
e.printStackTrace();
}
} else jf = ifs.get(frameName); //已存在则直接调用
return jf;
}
三、总结
1. 使用Class.forName( )静态方法的目的是为了动态加载类。在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。因此,单单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。
2. Class.forName()的作用是要求JVM查找并加载指定的类,首先要明白,java里面任何class都要装载在虚拟机上才能运行,而静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了,而且以后不会再走这段静态代码了。