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