Java面试基础篇——第十一篇:Class.forName和ClassLoader的区别

原创
2018/07/25 10:08
阅读数 610

Java中的Class.forName()ClassLoader都可以用来对类进行加载。Class.forName()除了将类的.class文件加载到JVM中 还会对类进行解释,执行类中的static块,而ClassLoader只会将.class文件加载到JVM,不会执行static块,只有在newInstance的时候才执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法才会调用构造函数,创建类的对象。

来看看Class.forName()的源码

   @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
		//第二个参数 true,表示是否初始化,初始化就是执行static代码
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

OK, 到这我们来做个小小的测试

public class Main {

    private static final String CLASS_NAME_1 = "com.developlee.springmvclearn.test.Test";
    private static final String CLASS_NAME_2 = "com.developlee.springmvclearn.test.Test2";

    public static void main(String[] args) throws Exception {

        testClassLoader(CLASS_NAME_1, CLASS_NAME_2);
        System.out.println("上面测试ClassLoader 下面测试Class.forName()");
        testClassForName(CLASS_NAME_1, CLASS_NAME_2);

    }

    private static void testClassLoader(String class1, String class2){
        Class<?> clazz1;
        Class<?> clazz2;
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        try {
            clazz1 = classLoader.loadClass(class1);
            clazz2 = classLoader.loadClass(class2);
            System.out.println("Class1: " + clazz1.getSimpleName() + ", Class2: " + clazz2.getSimpleName());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static void testClassForName(String class1, String class2){
        try {
            Class clazz1 = Class.forName(class1);
            Class clazz2 = Class.forName(class2);
            System.out.println("Class1: " + clazz1.getSimpleName() + ", Class2: " + clazz2.getSimpleName());
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

Test和Test2的代码

public class Test {
    static {
        System.out.println("静态代码块执行了...");
    }

}

public class Test2 {
    static {
        System.out.println("Test2 static code blocks is running !");
    }
}

看看执行的结果

Class1: Test, Class2: Test2
上面测试ClassLoader 下面测试Class.forName()
静态代码块执行了...
Test2 static code blocks is running !
Class1: Test, Class2: Test2

Process finished with exit code 0

发现ClassLoader并不会执行static代码块,而Class.forName()才会执行对类的初始化,这也就验证了文章开始我们所阐述的观点。

展开阅读全文
打赏
0
8 收藏
分享
加载中
liululee博主

引用来自“likai731008”的评论

对我这个初学者好有用
感谢你的肯定!
2018/07/25 16:18
回复
举报
对我这个初学者好有用
2018/07/25 12:31
回复
举报
更多评论
打赏
2 评论
8 收藏
0
分享
返回顶部
顶部