java反射中Class.forName和classloader差异对比

1.反射Class.forName和classloader对比

java使用反射时可以通过两种方式实现类加载,class.forName()和classLoader都可用来对类进行加载。那么二者有什么区别吗?

不同点:
1.class.forName()除了将类的.class文件加载到jvm中之外,默认还会对类进行初始化,执行类中的static块。
而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。

以下是的forName的实现代码:

public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

默认是会执行初始化操作的。

2.案例

下面通过代码演示两种加载方式的差异。

package reflect;

class LoadTest{
	static {
		System.out.println("########loadTest########");
	}
	public LoadTest() {
	}
}

public class ClassloaderTest {

	public static void main(String[] args) {
		String className = "reflect.LoadTest";
		System.out.println("以下是测试Classloader的效果:");
		testClassloader(className);

		System.out.println("========================");
		System.out.println("以下是测试Class.forName的效果:");
		testForName(className);
	}
	
	/**
	 * classloader 加载
	 * @param className
	 */
	private static void testClassloader(String className) {
		Class<?> c;
		ClassLoader loader = ClassLoader.getSystemClassLoader();
		try {
			c = loader.loadClass(className);
			System.out.println("testClassloader: " + c.getName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * forName 加载
	 * @param className
	 */
	private static void testForName(String className) {
		try {
			Class c = Class.forName(className);
			System.out.println("testForName:" + c.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果:

以下是测试Classloader的效果:
testClassloader: reflect.LoadTest
========================
以下是测试Class.forName的效果:
########loadTest########
testForName:reflect.LoadTest

猜你喜欢

转载自blog.csdn.net/cl2010abc/article/details/105531771
今日推荐