使用 Class.forName() 加載類
在一些應用中,我們無法事先知道使用者將會加載什麼類,而必須讓使用者指定類名類加載類,我們就可以用Class的靜態forName()方法來實現動態加載類,如下:
package CoreJava.day_2;
/**
* @author 李智
* @date 2016/12/4
*/
public class ForNameDemo {
public static void main(String[] args) {
try {
Class c = Class.forName(args[0]);
System.out.println("類名:" +
c.getName());
System.out.println("是否爲接口:" +
c.isInterface());
System.out.println("是否爲基本類型:" +
c.isPrimitive());
System.out.println("是否爲數組:" + c.isArray());
System.out.println("父類名:" +
c.getSuperclass().getName());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("沒有指定的類名");
} catch (ClassNotFoundException e) {
System.out.println("找不到指定類");
}
}
}
輸出:
java ForNameDemo java.util.String
類名:java.util.Scanner
是否爲接口:false
是否爲基本類型:false
是否爲數組:false
父類名:java.lang.Object
Class的靜態方法forName()方法有兩個版本,上面所示的是指定類名版本,還一個版本可以讓我們指定類名,加載時是否執行靜態代碼塊,指定類的加載器(Class loader):
static Class forName(String name, boolean initialize, ClassLoader loader)
上一篇寫到過,假設在加載類的時候,如果類中有定義靜態代碼塊則會執行它,我們可以使用forName的第二個版本,將initialize設爲false,如果在加載類時並不會馬上執行靜態代碼塊的代碼,而會在使用類實例對象時才執行靜態代碼塊,我們可以做一下測試:
package CoreJava.day_2;
/**
* @author 李智
* @date 2016/12/4
*/
public class TestClass2 {
static {
System.out.println("[執行靜態代碼塊]");
}
}
在這裏我們只定義了靜態代碼塊顯示一段信息,來觀察靜態代碼塊何時被執行。先用第一個版本來測試:
package CoreJava.day_2;
/**
* @author 李智
* @date 2016/12/4
*/
public class ForNameDemoV1 {
public static void main(String[] args) {
try {
System.out.println("加載TestClass2");
Class c = Class.forName("TestClass2");
System.out.println("TestClass2聲明");
TestClass2 test = null;
System.out.println("TestClass2實例對象");
test = new TestClass2();
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的類");
}
}
}
輸出:
加載TestClass2
[執行靜態代碼塊]
TestClass2聲明
TestClass2實例對象
Process finished with exit code 0
可以從結果看出,第一個版本的forName()方法在加載類之後,會馬上執行靜態代碼塊,再看看第二種結果怎麼樣:
package CoreJava.day_2;
/**
* @author 李智
* @date 2016/12/4
*/
public class ForNameDemoV2 {
public static void main(String[] args) {
try {
System.out.println("加載TestClass2");
Class c = Class.forName(
"CoreJava.day_2.TestClass2",
false, // 加載類時不執行靜態代碼塊代碼
Thread.currentThread().getContextClassLoader());
System.out.println("TestClass2聲明");
TestClass2 test = null;
System.out.println("TestClass2實例對象");
test = new TestClass2();
} catch (ClassNotFoundException e) {
System.out.println("找不到指定的類");
}
}
}
輸出:
加載TestClass2
TestClass2聲明
TestClass2實例對象
[執行靜態代碼塊]
Process finished with exit code 0
由於在第二個版本的forName()方法中,把initialize設爲了false,所以加載類時並不會馬上執行靜態代碼塊,而會在類實例對象時纔去執行靜態代碼塊代碼,第二個版本的forName()方法需要一個類加載器(Class loader)。