星期三, 10月 31, 2012

OCPJP Day 13


*系統參數(System Properties)
  • 類似作業系統環境變數的概念, 可以算是JVM的環境變數
  • 透過System.getProperties方法可以回傳一個Properties的物件
  • 透過System.getProperty方法回傳一個代表某一命名property對應的字串值
  • 透過 -D 還可以新增新的property

*Properties 類別
  • Properties類別實作了property名稱和property值之前的對應關係(String to String)
  • propertyNames方法回傳一個包含所有property名稱的Enumeration物件
  • getProperty方法回傳一個代表某一個命名property的對應字串.


Notes:
  • Enumeration TS(Thread-safe), Iterator NTS(Non-Thread-safe)
  • Enumeration 會在指標上下各放一個指標(Before the first)(After the last) 來配合 hasMoreElements 以及 nextElement. 也就是如果有10個記憶體指標, 會有12個位置.


PropertiesDemo.java

package mod14;

import java.util.Enumeration;
import java.util.Properties;

public class PropertiesDemo {

public static void main(String[] args) {
Properties props = System.getProperties();
//下面那個Enumeration 以及 while 迴圈來取得properties, 也可以透過 props.list這個API來達成
props.list(System.out);
//分隔符號以下是用 Enumeration 以及 while 迴圈來取得properties
System.out.println("#########################################");

Enumeration propNames = props.propertyNames();
//
while (propNames.hasMoreElements()) {
String propName = (String) propNames.nextElement();
System.out.println("-------------------------------");
String property = props.getProperty(propName);
System.out.println("Property : " + propName + " is " + property + "");
}
}
}


Lab:

Lottery.java

package lab14;

import java.util.HashSet;
import java.util.Set;

public class Lottery {

public static void main(String[] args) {
//如果要排序就使用TreeSet(), 不排序就使用 HashSet()
Set<Integer> numbers = new HashSet();
int random;
while (numbers.size() != 6){
random = (int) Math.ceil(Math.random()*49);
numbers.add(random);
}
System.out.println(numbers);
}
}


*Chapter 12 Exception Assertion
  • Exception
    • Exception是被動的,用來表示一些非預期的情況.
    • 執行時期才會發生.
    • Exception都是類別, 而且每一個套件中均有各自Exception類別.
    • 使用者回報bug的時候常用Exception.
  • Assertion
    • Assertion是主動的
    • 當程式時好時壞的時候, 會使用Assertion

*Exception架構與分類

Throwable
  • Error: 硬體錯誤, JVM錯誤 (嚴重型的錯誤, 不處理)(Unchecked Exception)
  • Exception
    • Runtime Exception: 邏輯上的錯誤(Unchecked Exception 編譯器無法檢查)
      • 80%通常代表程式有瑕疵, 語法上無法處理
      • 20%User Error, 考慮處理他
    • Checked Exception
      • Checked 代表編譯器會檢查
      • 在語法上面一定要處理
        • try-catch
        • throw / throws


AddArguments.java

package mod12;

public class AddArguments {

public static void main(String[] args) {
//
int sum = 0;
for (String s : args) {
sum += Integer.parseInt(s);
}
//
System.out.println("Sum= " + sum);
System.out.println("Thannks you !! Bye!!");
}
}

於外部執行此 java 程式例如(執行命令時位於執行檔案頂層目錄)
java mod12/AddArguments 1 2 3

輸出結果為
Sum= 6
Thannks you !! Bye!!


Notes:
  • 如果有使用 try-catch, 程式會繼續運作下去, 不是直接中斷

Lab: try-catch

AddArguments.java

package mod12;

public class AddArguments {

public static void main(String[] args) {
//
try {
int sum = 0;
for (String s : args) {
sum += Integer.parseInt(s);
}
//
System.out.println("Sum= " + sum);
} catch (NumberFormatException numberFormatException) {
// Report to User 回報使用者輸出的字串
System.out.println("There might be some mistakes with your input.");
}
System.out.println("Thannks you !! Bye!!");
}
}


如果只針對該行程式進行 try-catch

AddArguments.java

package mod12;

public class AddArguments {

public static void main(String[] args) {
//
int sum = 0;
for (String s : args) {
try {
sum += Integer.parseInt(s);
} catch (NumberFormatException numberFormatException) {
System.out.println("Input[ "+s+" ]not correct, So we don't add it!");
}
}
//
System.out.println("Sum= " + sum);
System.out.println("Thannks you !! Bye!!");
}
}


這樣既使輸入的參數有誤, 正確的參數也會加總
例如
java mod12/AddArguments 1 2 3 for 2

輸出結果

Input[ for ]not correct, So we don't add it!
Sum= 8
Thannks you !! Bye!!

Notes:
  • try-catch 陳述式可以多個catch 子句
    • 如果Excepton 沒有繼承關係,
      • catch順序可以隨便排
    • 如果Exception 有繼承關係( java 會使用 instance of 來詢問)
      • catch 必須先catch 子類別, catch 上層的父類別(不然詢問父類別 instance of 一定會回傳 true, 就不會執行下面的catct)
      • 最後會去catch Exception 類別(因為他是所有Exception的父類別)
Exception (有父類別與子類別的關係)
  • IOException (Input / Output 出錯有關)
    • FileNotFoundException
    • EOFException
  • HRException (使用者自訂, 通用大分類的Exception)
    • GenReportException(子類別通常比較細微且實際)
    • CalcSalayException


*finallly 子句
  • 保護的機制
  • 無論如何一定會被執行的程式區塊.
  • 開啟串流要確保串流被關閉


Lab: finally

加上 finally

AddArguments.java

package mod12;

public class AddArguments {

public static void main(String[] args) {
//
// try {
int sum = 0;
for (String s : args) {
try {
sum += Integer.parseInt(s);
} catch (NumberFormatException numberFormatException) {
System.out.println("Input[ "+s+" ]not correct, So we don't add it!");
}finally{
System.out.println("Finally exec!");
}
}
//
System.out.println("Sum= " + sum);
// } catch (NumberFormatException numberFormatException) {
// Report to User 回報使用者輸出的字串
// System.out.println("There might be some mistakes with your input.");
//}
System.out.println("Thannks you !! Bye!!");
}
}


執行該程式
java mod12/AddArguments 1 2 3 for 2

輸出結果為

Finally exec!
Finally exec!
Finally exec!
Input[ for ]not correct, So we don't add it!
Finally exec!
Finally exec!
Sum= 8
Thannks you !! Bye!!

上面會看到輸入 5 個參數, 就確定執行5final 的程式


Notes:
  • Call Stack Mechanism
    • Exception 如果一直往上層(呼叫者丟),丟給 main() 再丟給JVM, JVM 會終止這個程式, 這個稱為Call Stack Mechanism
假如 Exception 的架構如下
Exception ← AException ← BException ←CException

程式如下

public void test(){

try{
1
2
3
4
}catch(BException e){
A
}finally{
B
}
C
}

Case 1 如果程式沒有發生任何Exception
1 → 2 → 3 → 4 → A → B → C

Case 2 如果程式在 3 發生BException
1 → 2 → 3 → 4 → A → B → C

Case 3 如果程式在3發生RuntimeException
1 → 2 → 3 → B → Call Stack Mechanism

Case 4 基於Case 2 但是catch A的程式碼內有 return; catch 區塊
1 → 2 → 3 → A → B → return


Notes:
  • 不管如何, finally都會執行


*常見的例外狀況
  • NullpointException
  • NumberFormatException
  • ArithmeticException
    • 分子與分母都是整數, 然後除以0

*例外處理或宣告的規則
  • 處理
    • 使用try-catch-finally區塊來處理
  • 宣告
    • 透過throws子句來宣告程式(往外面丟)(一定是屬於Checked Exception)

關鍵字有三個是動詞加上s (3人稱)
  • extends
  • implements
  • throws


public class Parent{
//這邊的 throws 有加上s
public void work() throws BException{
//狀況1 if ( … ) { throw new BException(); } //這邊throw沒有加上 s, 命令式, 祈使句
//方法本身即為丟出BException的源頭

//狀況2 ( new Staffing()).doStaff();
// 方法內部去呼叫會丟出BExceptionAPI但是並未使用try-catch來加以處理

}
}

public class Staffing{
public void doStaff()
throws BException{
}
}

Notes:
  • 所以如果方法本身是處理throw的源頭就不會加上s, 反之如果是呼叫別的API就會加上s

沒有留言: