第五週動手動腦1
阿新 • • 發佈:2018-11-07
結果:
1 package second; 2 3 public class Test { 4 /* 5 * 類的初始化塊 6 */ 7 { 8 value=100; 9 } 10 public int value=200;//欄位的初始值 11 12 public Test(){ 13 } 14 /* 15 * 建構函式初始化 16 */ 17 public Test(int value){ 18 this.value=value; 19 } 20 public static void main(String[] args){ 21 Test obj=new Test(); 22 System.out.println(obj.value);//結果 100 23 24 obj=new Test(300); 25 System.out.println(obj.value);//結果 300 26 } 27 }
總結:在執行類成員定義時,指定的預設值或類的初始化塊,執行哪個? 看哪個“排在後面”
注:類的初始化塊不接受任何引數,而且,只要建立類的物件,它們就會被執行。
所以,類的初始化塊適合於封裝那些“物件建立時,必須執行的程式碼”
二、類的靜態欄位
1.例如:
1 class Employee{ 2 String name; 3 long salary; 4 static int total; 5 }View Code
2.訪問類的靜態欄位:通過物件名或類名作為字首訪問靜態資料
2.1類名直接訪問(推薦使用):Employee.total=1;
2.2物件名訪問:
Employee newhire=new Employee();
newhire.total=1;
三、類的靜態初始化塊
1.例子
1 package first; 2 3 4 class Root//父類 5 { 6 static{ 7 System.out.println("Root的靜態初始化塊"); 8 } 9 { 10 System.out.println("Root的普通初始化塊"); 11 } 12 public Root() 13 { 14 System.out.println("Root的無引數的構造器"); 15 } 16 } 17 class Mid extends Root 18 { 19 static{ 20 System.out.println("Mid的靜態初始化塊"); 21 } 22 { 23 System.out.println("Mid的普通初始化塊"); 24 } 25 public Mid() 26 { 27 System.out.println("Mid的無引數的構造器"); 28 } 29 public Mid(String msg) 30 { 31 //通過this呼叫同一類中過載的構造器 32 this(); 33 System.out.println("Mid的帶引數構造器,其引數值:" + msg); 34 } 35 } 36 class Leaf extends Mid//子類 37 { 38 static{ 39 System.out.println("Leaf的靜態初始化塊"); 40 } 41 { 42 System.out.println("Leaf的普通初始化塊"); 43 } 44 public Leaf() 45 { 46 //通過super呼叫父類中有一個字串引數的構造器 47 super("Java初始化順序演示"); 48 System.out.println("執行Leaf的構造器"); 49 } 50 51 } 52 53 public class TestStaticInitializeBlock 54 { 55 public static void main(String[] args) 56 { 57 new Leaf(); 58 59 } 60 }
結果:
2.總結:
2.1靜態初始化塊只執行一次。
2.2建立子型別的物件時,會導致父型別的靜態初始化塊的執行
四、類的靜態方法(類的靜態方法只能訪問類的靜態成員!!!)
1.例如
1 class Employee{ 2 String name; 3 long salary; 4 short employee_id; 5 static int total; 6 static void clear(){ 7 total=0; 8 } 9 }View Code
2.如何在靜態方法中訪問類的例項成員(即沒有附加static關鍵字的欄位或方法)?
public class Example { int x = 3;//類的例項變數,初始化值為3 static int y = 4;//類的靜態變數,初始化值為4 public static void method()//靜態方法 { System.out.println("例項變數x = " + new Example().x);//在靜態方法中訪問類的例項變數需首先進行類的例項化 System.out.println("靜態變數y = " + y);//在靜態方法中可直接訪問類的靜態變數 } public static void main(String[] args) { Example.method(); Example ex = new Example(); System.out.println("x = " + ex.x); } }View Code
解決方案:在靜態方法中訪問類的例項變數需首先進行類的例項化
類中靜態的方法或者屬性,本質上來講並不是該類的成員,在java虛擬機器裝在類的時候,這些靜態的東西已經有了物件,它只是在這個類中"寄居",不需要通過類的構造器(建構函式)類實現例項化;而非靜態
的屬性或者方法,在類的裝載是並沒有存在,需在執行了該類的建構函式後才可依賴該類的例項物件存在。
在外部呼叫靜態方法時,可以使用"類名.方法名"的方式,也可以使用"物件名.方法名"的方式。而例項方法只有後面這種方式。也就是說,呼叫靜態方法可以無需建立物件。
五、Integer的詭異性
public static void main(String[] args){ Integer i1=100; Integer j1=100; System.out.println(i1=j1);//true Integer i2=129; Integer j2=129; System.out.println(i2=j2);//false }
原因:檢視原始碼可知,在通過valueOf方法建立Integer物件的時候,如果數值在[-128,127]之間,便返回指向IntegerCache.cache中已經存在的物件的引用;否則建立一個新的Integer物件。
1 * This method will always cache values in the range -128 to 127, 2 * inclusive, and may cache other values outside of this range. 3 * 4 * @param i an {@code int} value. 5 * @return an {@code Integer} instance representing {@code i}. 6 * @since 1.5 7 */ 8 public static Integer valueOf(int i) { 9 if (i >= IntegerCache.low && i <= IntegerCache.high) 10 return IntegerCache.cache[i + (-IntegerCache.low)]; 11 return new Integer(i); 12 }
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }