相同点:两者都可以对类进行加载。
区别:Class.forName除了将.class加载到jvm中,还会对类进行解释,并执行类的静态代码块。
classloader只是将.class加载到jvm中,不会执行static中的内容,只有在newInstance才会执行static块。
Class.forName源码如下:
@CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }
@CallerSensitive public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { Class<?> caller = null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { // Reflective call to get caller class is only needed if a security manager // is present. Avoid the overhead of making this call otherwise. caller = Reflection.getCallerClass(); if (sun.misc.VM.isSystemDomainLoader(loader)) { ClassLoader ccl = ClassLoader.getClassLoader(caller); if (!sun.misc.VM.isSystemDomainLoader(ccl)) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } } } return forName0(name, initialize, loader, caller); }
第二个参数initialize是指Class被是否被初始化,初始化就是执行静态代码块。默认是true;
使用:
public class Line { static { System.out.println("初始化执行!"); } public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> aClass = Class.forName("com.example.demo.Line"); ClassLoader loader = ClassLoader.getSystemClassLoader(); Class<?> aClass1 = loader.loadClass("com.example.demo.Line"); Line instance = (Line) aClass1.newInstance(); } }执行结果可以看出,ClassLoader只有在newInstance的时候才执行初始化代码;