Java中的class.forName和classLoader都可以用来对类的加载。
class.forName除了把类加载到JVM中,还会对类进行解释,执行类的static代码块;
classLoader只是把类加载到JVM中,只有在调用newInstance的时候才会去执行static代码块;
class.forName的源码如下,对static块的执行是可用控制的,第二个参数为True则执行
public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }
理论要与实践相结合,接下来测试一下
两个类,分布包含静态代码库
public class Point { static{ System.out.println("point static block"); } } public class Line { static{ System.out.println("Line static block..."); } }
测试类
public class ClassForNameTest { public static void main(String[] args){ String wholenameLine="classloader.Line"; String wholenamePoint="classloader.Point"; System.out.println("classForName test...."); testClassForNameMethod(wholenameLine,wholenamePoint); System.out.println("__________________________________"); testClassLoaderMethod(wholenameLine,wholenamePoint); } private static void testClassLoaderMethod(String wholenameLine, String wholenamePoint) { ClassLoader classLoader=ClassLoader.getSystemClassLoader(); try { Class line=classLoader.loadClass(wholenameLine); Class point=classLoader.loadClass(wholenamePoint); System.out.println(line.getName()); System.out.println(point.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private static void testClassForNameMethod(String wholenameLine, String wholenamePoint) { try { Class line = Class.forName(wholenameLine); Class point =Class.forName(wholenamePoint); System.out.println(line.getName()); System.out.println(point.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
结果如下: 可用看到class.forName的输出有Line和Point类的静态代码库的输出,而使用classLoader则不会有; 如果静态代码块换成静态方法呢? 不会执行。
classForName test....
Line static block...
point static block
classloader.Line
classloader.Point
__________________________________
classloader.Line
classloader.Point