1、java中class.forName()和classLoader都可用來對類進行加載。
不同:1)class.forName()除了将類的.class檔案加載到jvm中之外,還會對類進行解釋,執行類中的static塊,還會執行給靜态變量指派的靜态方法
2)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();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}// 第二個參數,是指Class被loading後是不是必須被初始化。 不初始化就是不執行static的代碼即靜态代碼
測試代碼:
package com.ntj.reflect;
public class Line {
static {
System.out.println("靜态代碼塊執行:loading line");
}
}
package com.ntj.reflect;
public class Point {
static {
System.out.println("靜态代碼塊執行:loading point");
}
}
public class ReflectTest {
public static void main(String[] args) {
String wholeNameLine = "com.ntj.reflect.Line";
String wholeNamePoint = "com.ntj.reflect.Point";
System.out.println("下面是測試Classloader的效果");
testClassloader(wholeNameLine, wholeNamePoint);
System.out.println("----------------------------------");
System.out.println("下面是測試Class.forName的效果");
testForName(wholeNameLine, wholeNamePoint);
}
private static void testClassloader(String wholeNameLine, String wholeNamePoint) {
Class<?> line;
Class<?> point;
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try {
line = classLoader.loadClass(wholeNameLine);
point = classLoader.loadClass(wholeNamePoint);
System.out.println("line " + line.getName());
System.out.println("point " + point.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
private static void testForName(String wholeNameLine, String wholeNamePoint) {
try {
Class<?> line = Class.forName(wholeNameLine);
Class<?> point = Class.forName(wholeNamePoint);
System.out.println("line " + line.getName());
System.out.println("point " + point.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
測試結果:
1)classloader沒有執行靜态代碼塊
2)Class.forName執行了靜态代碼塊
修改Line的代碼,除了原來的簡單的一個靜态代碼塊以外,又添加了構造方法,靜态方法,以及靜态變量,且,靜态變量被一個靜态方法指派。
package com.ntj.reflect;
public class Line {
static {
System.out.println("靜态代碼塊執行:loading line");
}
public static String s = getString();
private static String getString() {
System.out.println("給靜态變量指派的靜态方法執行:loading line");
return "ss";
}
public static void test() {
System.out.println("普通靜态方法執行:loading line");
}
{
System.out.println("要是普通的代碼塊呢?");
}
public Line() {
System.out.println("構造方法執行");
}
}
靜态變量指派的靜态方法被執行了
轉:http://blog.csdn.net/qq_27093465/article/details/52262340