Java反射中Class.forName与classLoader的区别

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

原文地址:https://www.cnblogs.com/dpains/p/7228074.html