请问: 一个类装载的问题

请问: Class.forName(classname) 与
ClassLoader.loadClass(classname)有区别吗?

ClassLoader.loadClass(classname) 在性能上可能要好些

能说详细点吗? 谢谢

实质是一样的,Class.forName()要调用 ClassLoader.loadClass()来获得类对象。
性能也不会有太大的区别,因为耗时的操作在loadClass内部。

首先声明一点:ClassLoader的loadClass()方法不是静态方法。因此你的问题有错误。

Class.forName()使用代码当前所在类的加载器来加载你需要的类。
而ClassLoader的实例方法指派特定的加载器来加载类。

Class clazz = Class.forName("XXX.XXX");

ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("XXX.XXX");
都可以装载一个类那么他们的区别是什么呢?

进一步研究Class.forName()是调用Class.forName(name, initialize, loader);
也就是Class.forName("XXX.XXX"); 等同与 Class.forName("XXX.XXX", true, CALLCLASS.class.getClassLoader());
第二个参数表示装载类的时候是否初始化该类, 即调用类的静态块的语句及初始化静态成员变量。

Class clazz = cl.loadClass("XXX.XXX"); 没有指定是否初始化的选项。只有执行clazz.newInstance();时才能够初始化类。可以说 Class.forName("XXX.XXX", false, cl)执行过程是一致的。只是ClassLoader.loadClass()是更底层的操作。

"Class clazz = Class.forName("XXX.XXX");

ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("XXX.XXX");
都可以装载一个类那么他们的区别是什么呢?
"
前者使用当前类的加载器加载,后者是用当前线程加载器加载,二者一般是一样的,但也可能不一样,我猜想可能是这样:
一般生成一个线程,先实例化一个Runnable实现类,假设这个实现类用c1加载器,然后实例化一个Thread(Runnable),用Thread的start()方法运行线程,这个Thread()的加载器是c2,倘若在Runnable实现类中用Class.forName用c1加载器,Thread.currentThread().getContextClassLoader()则返回c2,我的猜想:)

Class.forName(classname)当类加载完以后立即进行静态代码的执行。
ClassLoader.loadClass(classname)而这个方法在加载类后,要等到真正实例化一个类的时候才会去执行静态初始化代码。


不过也可以采用三个参数的forName方法,将第二个参数指定为false,这样以来效果就和ClassLoader.loderclass()一样了。