1.反射Class.forName和classloader对比
java使用反射时可以通过两种方式实现类加载,class.forName()和classLoader都可用来对类进行加载。那么二者有什么区别吗?
不同点:
1.class.forName()除了将类的.class文件加载到jvm中之外,默认还会对类进行初始化,执行类中的static块。
而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
以下是的forName的实现代码:
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
默认是会执行初始化操作的。
2.案例
下面通过代码演示两种加载方式的差异。
package reflect;
class LoadTest{
static {
System.out.println("########loadTest########");
}
public LoadTest() {
}
}
public class ClassloaderTest {
public static void main(String[] args) {
String className = "reflect.LoadTest";
System.out.println("以下是测试Classloader的效果:");
testClassloader(className);
System.out.println("========================");
System.out.println("以下是测试Class.forName的效果:");
testForName(className);
}
/**
* classloader 加载
* @param className
*/
private static void testClassloader(String className) {
Class<?> c;
ClassLoader loader = ClassLoader.getSystemClassLoader();
try {
c = loader.loadClass(className);
System.out.println("testClassloader: " + c.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* forName 加载
* @param className
*/
private static void testForName(String className) {
try {
Class c = Class.forName(className);
System.out.println("testForName:" + c.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
以下是测试Classloader的效果:
testClassloader: reflect.LoadTest
========================
以下是测试Class.forName的效果:
########loadTest########
testForName:reflect.LoadTest