在java程序中每一個(gè)類都有一個(gè)Class對象,被保存在同名的.Class對象當(dāng)中,JVM會(huì)使用類加載器加載Class文件生成類的對象信息.
當(dāng)我們創(chuàng)建一個(gè)類的對象或者調(diào)用這個(gè)對象的靜態(tài)方法,jvm會(huì)自動(dòng)加載類的對象信息
獲得類的對象信息
我們一般常用用兩種方式獲得類的對象信息.
1. 我們可以用Class.forName()方法動(dòng)態(tài)的根據(jù)類名獲得一個(gè)類的Class對象.
1: /**
2: * 使用此方法為自動(dòng)初始化靜態(tài)變量和執(zhí)行static塊的代碼
3: * 如果找不到對象會(huì)拋出一個(gè)ClassNotFoundException
4: */
5: Class second = Class.forName("classLoad.Second");
2. 我們還可以用Class class = ClassName.class 來直接獲取一個(gè)類的類型信息,但用它和Class.forName()獲取類的對象
引用信息在靜態(tài)塊時(shí)的執(zhí)行時(shí)間上不同,看下面的例子:
一個(gè)普通類信息
1: interface Interface{
2: public static String interFlag = "接口";
3:
4: }
5:
6: class Parent implements Interface{
7: public static String parntFLAG = "父類靜態(tài)變量";
8: static{
9: final String flag2 = "flag2";//static 區(qū)中只能用final修飾
10: System.out.println("我在父類靜態(tài)區(qū)里面!"+parntFLAG);
11: }
12:
13: public Parent(){
14: System.out.println("我在父類構(gòu)造函數(shù)里面!");
15: }
16: }
17:
18:
19: class Son extends Parent{
20: public static String sonFLAG = "子類類靜態(tài)變量";
21: static{
22: System.out.println("我在子類靜態(tài)區(qū)里面!"+sonFLAG);
23: }
24:
25: public Son(){
26: System.out.println("我在子類構(gòu)造函數(shù)里面!");
27: }
28: }
1: interface Interface{
2: public static String interFlag = "接口";
3:
4: }
5:
6: class Parent implements Interface{
7: public static String parntFLAG = "父類靜態(tài)變量";
8: static{
9: final String flag2 = "flag2";//static 區(qū)中只能用final修飾
10: System.out.println("我在父類靜態(tài)區(qū)里面!"+parntFLAG);
11: }
12:
13: public Parent(){
14: System.out.println("我在父類構(gòu)造函數(shù)里面!");
15: }
16: }
17:
18:
19: class Son extends Parent{
20: public static String sonFLAG = "子類類靜態(tài)變量";
21: static{
22: System.out.println("我在子類靜態(tài)區(qū)里面!"+sonFLAG);
23: }
24:
25: public Son(){
26: System.out.println("我在子類構(gòu)造函數(shù)里面!");
27: }
28: }
使用這種方法引用類的對象不會(huì)始化靜態(tài)變量和執(zhí)行靜態(tài)塊信息,這些代碼方法會(huì)在首次引用時(shí)執(zhí)行.
如下引用父類的靜態(tài)變量,不會(huì)執(zhí)行子類的靜態(tài)塊.
1: public class ClassLoad {
2: public static void main(String[] args) throws ClassNotFoundException {
3:
4: //Son son = new Son();
5: /**
6: * 我們使用一個(gè)類的時(shí)候需要進(jìn)行以下3項(xiàng)工作.
7: * 1.加載,
8: * 2.鏈接
9: * 3.初始化,此步會(huì)初始化靜態(tài)變量和執(zhí)行靜態(tài)塊信息,但是這種方法會(huì)在
10: * 真正調(diào)用方法時(shí)執(zhí)行
11: */
12: Class son = Son.class;
13: System.out.println("靜態(tài)區(qū)的初始化會(huì)在調(diào)用時(shí)執(zhí)行!");
14: // parntFLAG 是父類的靜態(tài)變量
15: // 此處只會(huì)執(zhí)行父類的靜態(tài)快
16: System.out.println(Son.parntFLAG);
17:
18: /**
19: * 運(yùn)行結(jié)果
20: *靜態(tài)區(qū)的初始化會(huì)在調(diào)用時(shí)執(zhí)行!
21: *我在父類靜態(tài)區(qū)里面!父類靜態(tài)變量
22: *父類靜態(tài)變量
23: */
24: }
25: }
打印子類的靜態(tài)變量,所有的代碼都會(huì)執(zhí)行
1:
2: public class ClassLoad {
3: public static void main(String[] args) throws ClassNotFoundException {
4:
5: //Son son = new Son();
6: /**
7: * 我們使用一個(gè)類的時(shí)候需要進(jìn)行以下3項(xiàng)工作.
8: * 1.加載,
9: * 2.鏈接
10: * 3.初始化,此步會(huì)初始化靜態(tài)變量和執(zhí)行靜態(tài)塊信息,但是這種方法會(huì)在
11: * 真正調(diào)用方法時(shí)執(zhí)行
12: */
13: Class son = Son.class;
14: System.out.println("靜態(tài)區(qū)的初始化會(huì)在調(diào)用時(shí)執(zhí)行!");
15: // parntFLAG 是父類的靜態(tài)變量
16: // 此處只會(huì)執(zhí)行父類的靜態(tài)快
17: System.out.println(Son.sonFLAG);
18:
19: /**
20: * 運(yùn)行結(jié)果
21: * 靜態(tài)區(qū)的初始化會(huì)在調(diào)用時(shí)執(zhí)行!
22: * 我在父類靜態(tài)區(qū)里面!父類靜態(tài)變量
23: * 我在子類靜態(tài)區(qū)里面!子類類靜態(tài)變量
24: * 子類類靜態(tài)變量
25: */
26: }
27: }
但是使用Class.forName 類加載時(shí)就會(huì)完成初始化工作.
1: public class ClassLoad {
2: public static void main(String[] args) throws Exception {
3: /**
4: * 使用Class.forName會(huì)自動(dòng)加載所有靜態(tài)區(qū)的信息
5: */
6: Class son = Class.forName("classLoad.Son");
7: Son instance = (Son)son.newInstance();
8: /*
9: * 執(zhí)行結(jié)果
10: * 我在父類靜態(tài)區(qū)里面!父類靜態(tài)變量
11: * 我在子類靜態(tài)區(qū)里面!子類類靜態(tài)變量
12: * 我在父類構(gòu)造函數(shù)里面!
13: * 我在子類構(gòu)造函數(shù)里面!
14: */
15:
16: }
17: }