03-類與方法
一、如果一個類中既有初始化塊,又有構造方法,同時還設定了字段的初始值,誰說了算?以下代碼輸出結果是什麽?
請依據代碼的輸出結果,自行總結Java字段初始化的規律。
執行結果:
當“public int field=100;”在“{field=200;}”之前時,field初始化數值是由“{field=200;}”說了算;當“public int field=100;”在“{field=200;}”之後時,field初始化數值是由“public int field=100;”說了算。也就是說,那句話在後邊,後執行,則哪句話說了算。
註:類字段的初始化順序
- 執行類成員定義時指定的默認值或類的初始化塊,到底執行哪一個要看哪一個“排在前面”。
- 執行類的構造函數。。
類的初始化塊不接收任何的參數,而且只要一創建類的對象,它們就會被執行。因此,適合於封裝那些“對象創建時必須執行的代碼”。
二、請運行TestStaticInitializeBlock.java示例,觀察輸出結果,總結出“靜態初始化塊的執行順序”。
代碼:
1 package shiyan3; 2 class InitializeBlockClass { 3 { 4 field=200; 5 } 6 public int field=100; 7 public InitializeBlockClass(int value)8 { 9 this.field=value; 10 } 11 12 public InitializeBlockClass() 13 { 14 15 } 16 17 public static void main(String[] args) { 18 // TODO Auto-generated method stub 19 InitializeBlockClass obj=new InitializeBlockClass(); 20 System.out.println(obj.field);21 22 obj=new InitializeBlockClass(300); 23 System.out.println(obj.field); 24 } 25 }
執行結果:
靜態初始化塊的執行順序:
(1) 先執行靜態初始化塊,再執行普通方法。靜態初始化塊只執行一次。
(2) 創建子類型的對象時,也會導致父類型的靜態初始化塊的執行。
三、一個有趣的問題
靜態方法中只允許訪問靜態數據,那麽,如何在靜態方法中訪問類的實例成員(即沒有附加static關鍵字的字段或方法)?
請編寫代碼驗證你的想法。
1 package shiyan3; 2 public class Example 3 { 4 static int x = 1;//類的靜態變量,初始化值為4 5 int y = 2; //類的實例變量,初始化值為3 6 public static void method()//靜態方法 7 { 8 System.out.println("靜態變量x = " + x);//在靜態方法中可直接訪問類的靜態變量 9 System.out.println("實例變量y = " + new Example().y);//在靜態方法中訪問類的實例變量需首先進行類的實例化 10 } 11 12 public static void main(String[] args) 13 { 14 Example.method(); 15 Example xm = new Example(); 16 System.out.println("y = " + xm.y); 17 } 18 }
四、神奇代碼
兩對整數明明完全一樣,為何一個輸出true,一個輸出false?
提示:
使用javap來分析生成class文件,看它調用了Interger類的哪個方法,然後打開JDK源文件查看源碼,就可以找到答案。
Integer=100; 實際上調用的是Integer.valueOf(int i);
因為從-127到128之間的Integer數,Java在Integer中有事先緩存好的原型對象,每次返回的都是同一個Integer對象,只有不在這個範圍的數才會新創建出一個Integer,最後所指都不是同一個對象,所以比較的不是同一個對象。
五、使用類的靜態字段和構造函數,我們可以跟蹤某個類所創建對象的個數。請寫一個類,在任何時候都可以向它查詢“你已經創建了多少個對象?”。
設計思想:
每次執行分為3個選擇:1-創建對象,2-查詢已創建對象個數,3-退出。
若選擇1,之後要輸入創建的對象個數,以對象數組的形式創建,程序循環,每次創建的對象數依次累加。
若選擇2,可隨時查詢已經創建的對象個數。
若選擇3,可隨時退出。
代碼:
1 package shiyan3; 2 //信1605-2 20163588 王金萱 3 import java.util.Scanner; 4 public class countDuixiang { 5 public static void main(String[] args) 6 { 7 Duixiang oo=new Duixiang(); 8 oo.f(); 9 } 10 } 11 class Duixiang 12 { 13 static int n; 14 static int count; 15 public Duixiang() 16 { 17 count=n; 18 } 19 public void f() 20 { 21 int j=0; 22 Scanner in=new Scanner(System.in); 23 do 24 { 25 System.out.println("1-創建對象 2-查詢已創建對象個數 3-退出"); 26 j=in.nextInt(); 27 if(j==1) 28 { 29 System.out.print("請輸入要創建的對象個數:"); 30 int m=in.nextInt(); 31 Duixiang d[]=new Duixiang[m]; 32 n+=m; 33 Duixiang w3=new Duixiang(); 34 System.out.println("創建成功!"); 35 } 36 if(j==2) 37 { 38 System.out.println("你已經創建了"+Duixiang.count+"個對象"); 39 } 40 }while(j!=3); 41 } 42 }
執行結果:
03-類與方法