課程講義

Download Report

Transcript 課程講義

第8章 生命期的探討與列舉類型
8-1 變數種類與其生命期
8-2 方法種類與呼叫方式
8-3 類別成員的匯入
8-4 main()方法的參數傳遞與系統屬性設定
8-5 內部類別
8-6 Java列舉類型
8-7 資源回收機制
第8章 生命期的探討與列舉類型 - 2
8-1 變數種類與其生命期
變數依照存留在記憶體的時間長短可以分成4種:
類別變數(Class Variable)
實體變數(Instance Variable)
方法變數(Method Variable)
區塊變數(Block Variable)
第8章 生命期的探討與列舉類型 - 3
class Book{
//冠上static修飾詞的即為類別變數
static int count = 0;
//實體變數就是之前所說的屬性
String name = "Java程式設計";
//宣告在方法的小括號或大括號內的變數就是方法變數
void contents(int chapter){
//宣告在迴圈區塊內的變數是區塊變數
for(int i=1; i<=chapter; i++)
System.out.print(i);
}
}
1. 只有類別和實體變數可以加上存取修飾詞;方法和區塊變數
只提供該區塊內存取,所以不可冠上存取修飾詞。
2. 區域變數(Local Variable)就是指方法變數與區塊變數,區
域變數沒有預設初始值。
第8章 生命期的探討與列舉類型 - 4
各種變數記憶體配置示意圖
第8章 生命期的探討與列舉類型 - 5
輸出結果
this.price = 580.0
price = 600.0
sum = 10
現在共有幾本書:1
第8章 生命期的探討與列舉類型 - 6
範例說明
• 第2行:count是計數器,所以宣告為static變數。
• 第3、4行:name、price都是實體變數。
• 第5行:建構式小括號內的name、price都是方法變數。
• 第6行:這裡的count指的是第2行的count。
• 第7行:「this.name」指的是第3行的name,如果省略「this」,指的
就是第5行的name,這就是所謂的遮蔽效果。
• 第8行:「this.price」指的是第4行的price。
• 第10行:price是show()方法的變數。
• 第11行:「this.price」指的是第4行的price。
• 第12行:這裡的price指的是第10行的price。
• 第13行:sum是show()方法的變數。
• 第14行:i是for迴圈的區塊變數,所以第16行不可使用。
• 第17行:這裡的sum指的是第13行的sum。
• 第18行:x是show()方法的變數,未給予初始值就不可存取。
• 第26行:「Book.count」指的是第2行的count。
第8章 生命期的探討與列舉類型 - 7
透過特殊存取方式:
1. 透過類別名稱存取,一定是類別變數。
2. 透過this可以存取類別或是實體變數。
沒有透過特殊存取方式:
1. 從該變數的存取式向上尋找宣告式。
2. 若該區塊內找不到宣告式則跳出該區塊,
繼續向上尋找。直到找到宣告式為止。
第8章 生命期的探討與列舉類型 - 8
實體變數與類別變數容易混淆,參看下面範例:
輸出結果
Book.count = 3
book1.count = 3
book1.num = 2
book2.num = 1
範例說明
• 第13、14行:book1連續2次呼叫第4行的add()方法,不僅將類別變數count連續遞增2次,也將自己
所屬實體變數num連續遞增2次。
• 第15行:book2呼叫add()方法,會讓類別變數count再遞增1次;也讓所屬實體變數num遞增1次。
• 第16、17行:不論使用「Book.count」或「book1.count」,存取的都是第2行的類別變數count。
• 第18行:「book1.num」代表存取book1自己的實體變數。
• 第19行:「book2.num」代表存取book2自己的實體變數。
第8章 生命期的探討與列舉類型 - 9
8-2 方法種類與呼叫方式
Java的方法可分成:
實體方法(Instance Method)
-可以處理實體或類別變數。
類別方法(Class Method):
-僅能處理類別變數,不能置入實體變數或this、super。
第8章 生命期的探討與列舉類型 - 10
範例說明
• 第2行:count是計數器,所以宣告為static變數。
• 第4、6行:一旦建立Book物件,就會將count計數器累加。
• 第9行:可以直接使用類別名稱來呼叫getCount()方法並取得count值。
• 第10行:在類別方法內不可存取實體變數name,也不可使用this關鍵字。
• 第18行:呼叫第9行getCount()方法,以取得類別變數count的值。
• 第20行:呼叫第13行getName()方法,以取得實體變數name的值。
輸出結果
書的庫存:0
進1本新書: Java程式設計
進1本新書: SCJP認證手冊
書的庫存:2
第8章 生命期的探討與列舉類型 - 11
8-3 類別成員的匯入
類別成員都會冠上static修飾詞,並透過類別名稱
存取或呼叫,如果想要省略類別名稱,可以使用
類別成員的匯入功能-「import static」。
第8章 生命期的探討與列舉類型 - 12
Execute.java說明
• 第2行:使用「import static」功能。
• 第6行:實體成員沒有匯入功能,仍舊需透過物件名稱呼叫。
• 第7行:可省略類別名稱。
輸出結果
進1本新書: Java程式設計
書的庫存:1
第8章 生命期的探討與列舉類型 - 13
8-4 main()方法的參數傳遞與系統屬性設定
main()方法
1. public修飾詞:要被外部的JVM程式所呼叫。
2. static修飾詞:當物件還沒產生時,JVM就已呼叫
main方法。
3. 回傳類型為void:建立main()方法主要是執行程式,
所以不必有回傳值。
4. 參數是String陣列:允許使用者輸入多個參數值。
第8章 生命期的探討與列舉類型 - 14
1.
執行命令是「java Execute 250.0 580.0 600.0」
輸出結果為
總共幾本書:3
書價依序為:250.0 580.0 600.0
2.
執行命令是「java Execute」
輸出結果為
總共幾本書:0
書價依序為:
注意:未輸入參數,args.length會為0,而不會為null
第8章 生命期的探討與列舉類型 - 15
系統屬性的設定
執行命令可以加上參數「-D」以設定系統屬性,之後可
透過System.getProperty()、System.getProperties()方
法以取得對應的屬性值。
第8章 生命期的探討與列舉類型 - 16
執行命令是「java -Dbook.price=580.0 Property」
輸出結果為
prop1 = 580.0
prop2 = 580.0
注意:參數「-D」與屬性之間不可有任何空白字元
第8章 生命期的探討與列舉類型 - 17
8-5 內部類別
1個類別內再定義1個類別,則在外部的類別稱作
外部類別(Outer Class),在內部的類別就稱作
內部類別(Inner Class),又稱作巢狀式類別
(Nested Class)。
內部類別可分成4大類:static內部類別、實體內部
類別、方法內部類別、匿名內部類別。
第8章 生命期的探討與列舉類型 - 18
static內部類別
static內部類別如同static成員。static內部類別只能存取
外部類別的static成員,而不能存取實體成員。
第8章 生命期的探討與列舉類型 - 19
範例說明
• 第16行:static內部類別依附在外部類別上,所以使用「外部類別.內部類
別」來表示。而Inner就是該內部類別物件。
• 第17行:呼叫第6行show()方法。
• 第7行:存取第2行的x。
• 第8行:試圖存取第3行的y,但是static內部類別不能存取外部類別的實體
成員。
• 第9行:存取第5行的z。
輸出結果
Outer.x = 1
this.z = 3
第8章 生命期的探討與列舉類型 - 20
實體內部類別
實體內部類別如同實體成員。
範例說明
• 第16行:實體內部類別依附在物件實體上,所以要使用「new Outer().new
Inner();」來實體化內部類別的物件。
• 第7行:存取第2行的x。
• 第8行:存取第3行的y。
• 第9行:存取第5行的z。
輸出結果
Outer.x = 1
Outer.this.y = 2
this.z = 3
第8章 生命期的探討與列舉類型 - 21
方法內部類別
• 就是將內部類別宣告在方法內,這樣一來,就不再是成員。
• 如果存取外部的區域變數,這個區域變數會複製1份值給方法
內部類別,所以即便改變這副本的值,也不會影響原區域變數
的值,這樣一來改值就變得無意義了,所以乾脆就規定外部的
區域變數若要被方法內部類別存取,就必須冠上final修飾詞。
第8章 生命期的探討與列舉類型 - 22
輸出結果
x=1
y=2
z=3
a=4
範例說明
• 第16行:inner為方法內部類別的物件。
• 第17行:呼叫第8行的show()方法。
• 第9行:存取第2行的x。
• 第10行:存取第3行的y。
• 第11行:存取第7行的z。
• 第12行:存取第4行的a,必須冠上final。
• 第13行:存取第5行的b,必須冠上final。
第8章 生命期的探討與列舉類型 - 23
匿名內部類別
匿名內部類別只有類別內容但沒有類別名稱,通常用在
實作介面或改寫類別上。
輸出結果
電腦書資訊
範例說明
• 第7行:匿名內部類別實作了Book介面的show()方法。
• 第12行:呼叫第8行的show()方法。
第8章 生命期的探討與列舉類型 - 24
8-6 Java列舉類型
列舉資料是指有限度的資料,例如有家書店只賣
電腦類、漫畫類、商業類書籍,因為限制只有這3
類,所以這3類稱為列舉資料。
第8章 生命期的探討與列舉類型 - 25
早期處理列舉資料大多使用int類型,而且會加上public、
final、static等修飾詞。使用int類型會有許多缺點。
class BookType{
public final static int COMPUTER = 0; //電腦類
public final static int COMIC = 1; //漫畫類
public final static int BUSINESS = 2; //商業類
}
class Book{
private int type;
public void setType(int type){this.type = type;}
public int getType(){return type;}
}
class EnumTypeOld{
public static void main(String[] args){
Book book = new Book();
book.setType(BookType.COMPUTER);
//得到type值為0,無法聯想是電腦類書籍
System.out.println(book.getType());
//使用數字不直覺,所以可能設定錯誤的值:5
book.setType(5);
}
}
第8章 生命期的探討與列舉類型 - 26
Java列舉類型的規則
1. 列舉類型一定要加enum。
2. 列舉類型的屬性會自動加上public、final、static等修
飾詞,而且該列舉類型即為屬性的類型。
3. 列舉類型不可使用new關鍵字來實體化。
第8章 生命期的探討與列舉類型 - 27
範例說明
• 第1行:BookType是列舉類型,但其實它就是個類別。
• 第5、6行:屬性都是BookType類型。
• 第13、14行:列舉類型BookType不允許實體化。
• 第15行:book.getType()會回傳的COMPUTER。
輸出結果
書籍類型為:COMPUTER
第8章 生命期的探討與列舉類型 - 28
列舉類型也可以放在一般類別內,成為static或實體內
部類別。但不可為方法內部類別或匿名內部類別。
範例說明
• 第2行:BookType列舉類型成為實體內部類別。
• 第11行:因為BookType是內部類別,必須加上外部類
別的名稱。
輸出結果
書籍類型為:COMPUTER
第8章 生命期的探討與列舉類型 - 29
Java列舉類型的特色
1. 可以搭配switch-case。
2. 會自動繼承java.lang.Enum類別,而Enum類別改寫
Object類別的toString()方法,好讓屬性名稱直接回傳。
3. 列舉類型呼叫values()方法後即可轉成相同類型的陣列。
第8章 生命期的探討與列舉類型 - 30
輸出結果
書籍類型依序為:電腦類 漫畫類 商業類
範例說明
• 第3行:改寫toString()方法。
• 第5行:switch小括號內可以放列舉類型。
• 第22行:呼叫values()方法即可轉成陣列。
第8章 生命期的探討與列舉類型 - 31
8-7 資源回收機制
所謂Java資源回收機制(Garbage Collection,簡
稱GC),就是自動執行一支資源回收程式去偵測
是否有沒被參照到的實體,如果有,就會將該實
體的記憶體空間回收,並歸還給系統。
第8章 生命期的探討與列舉類型 - 32
資源回收的啟動要件
沒有任何物件參照到的實體,即成為資源回收的對象。
第8章 生命期的探討與列舉類型 - 33
第8章 生命期的探討與列舉類型 - 34
輸出結果
Java程式設計
SCJP認證手冊
範例說明
• 第17行:呼叫第7行getInstance()方法回傳的
實體會指派給book物件;而book物件原來參
照的實體就會成為資源回收對象。
• 第8行:book物件執行到第10行時會結束生
命期。
第8章 生命期的探討與列舉類型 - 35
資源回收的相關方法
1. System.gc()、Runtime.getRuntime().gc():“建
議”Java啟動資源回收機制。
2. finalize():當Java決定回收沒被參照到的實體之前,
會先呼叫此方法。
第8章 生命期的探討與列舉類型 - 36
輸出結果
Java程式設計的實體要被回收了!
範例說明
• 第17行:呼叫gc()方法會加快啟動回收機
制。當Java決定回收Book實體時,會呼
叫Book類別所定義的finalize()方法。