星期一, 11月 05, 2012

OCPJP Day 14


Lab: Exception

假如 Exception 的架構如下
Exception ← AException ← BException ←CException

AException.java

package mod12;

public class AException extends Exception {

public AException() {
}

public AException(String msg) {
super(msg);
}
}

BException.java

package mod12;
// BException 繼承AException
public class BException extends AException {
}


CException.java

package mod12;
//
public class CException extends BException {
}


Parent.java

package mod12;

public class Parent {
public void work() throws BException{
boolean sucess = false;
if(!sucess){
//Can throw BException or child excpetion
throw new BException();
}
}
public void work2() throws BException{
//
(new Staffing()).doStaff();
}
}


Staffing.java

package mod12;

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


*方法Overriding Exception
Overriding 方法
  • 可以丟出
    • 一到多個從Overridden方法宣告會丟出的Exception與子孫類別
    • 任意的的Unchecked Exception (Error / Runtime Exception)
  • 不可以丟出
    • 未被Overridden方法宣告會丟出的Exception
    • Overridden方法宣告會丟出Exception的父類別

Child.java

package mod12;

public class Child extends Parent {
//public void work() throws SQLException{ } //這個不行, 不可宣告未被宣告的Excepton
//public void work() throws AException{ } //這個不行, 宣告Exception的父類別
public void work() throws BException{ } // OK, 宣告子類別BException
public void work2() throws CException{ } // OK, 宣告子類別CException
}


修改 Parent.java

package mod12;

import java.io.IOException;

public class Parent {
public void work() throws BException{
boolean sucess = false;
if(!sucess){
//Can throw BException or child excpetion
throw new BException();
}
}
public void work2() throws BException{
//
(new Staffing()).doStaff();
}
//父類別有丟兩個類別
public void work3() throws BException,IOException{
}
}

修改 Child.java

package mod12;

import java.io.FileNotFoundException;

public class Child extends Parent {
//public void work() throws SQLException{ } //這個不行, 不可宣告未被宣告的Excepton
//public void work() throws AException{ } //這個不行, 宣告Exception的父類別
public void work() throws BException{
//No need to announce RuntimeException
} // OK, 宣告子類別BException
public void work2() throws CException{ } // OK, 宣告子類別CException
public void work3() throws BException, FileNotFoundException{
//Can throws BException or IOException or IOException's child Exception
//Can throws one or more Exceptions
}
}






*Assertion 概論
  • 系統上線時期的除錯工具
  • 用來註明並測試程式執行時應符合的假設條件
  • 測試可以在執行時期完全移除, 對程式執行速度完全不受影響
  • Assertion檢查的機制預設是被關閉
    • 藉由下列的指令啟動
      • java -enableassertions MyApplication
      • java -ea MyApplication

*Assertion 機制的建議用法
  • 使用Assertion機制來紀錄並確認單一方法的假設及內部邏輯是否合理
    • 內部執行的不變性(internal invariants)
    • 流程控制的不變性(control flow invariants)
    • 後置狀況及類別不變性(Postcondition and class invariants)


int a = ( new Staffing()).doStaff();

if ( a > 0 ){


} else {
//內部執行的不變性(internal invariants)
assert( a == 0 );

}


switch ( XXX ) {
case SPRING:
case SUMMER:
case FAIL:
case WINTER:

default:
//流程控制的不變性(control flow invariants)
assert(false);
}


*不適當的Assertion使用時機
  • 不要在public方法中用Assertion機制來檢查參數
  • 不要在Assertion的檢測中造成任何副作用







Lab: assert

TestAssertions.java

package mod12;

public class TestAssertions {

public static void main(String[] args) {
int testFlag = 100;
//設定 assert ,但是預設是關閉的如果沒有在 VM option設定 -ea 就不會啟動
assert( testFlag > 100);
//也可以在後面加上訊息
//assert( testFlag > 100 ):"This is an error Message";
System.out.println("Done!");
}
}



*Chapter 15 Java I/O

*I/O基礎概論: I/O stream (輸出入串流)
  • byte stream
    • 一次只能讀取1byte
    • 透過 InputStream讀資料
    • 透過OutputStream寫資料
  • char stream
    • 解決雙位元語系國家字元傳送及接收問題
    • 一次可以傳送2bytes (相當於1char)
    • 透過Reader讀取資料
    • 透過Writer寫資料


InputStreamReader
轉換的API, InputStream 轉成 Reader

OutputStreamWriter
轉換的API, OutputStream 轉成 Writer


*輸出入串流(I/O stream)
  • Node: (在第一線處理的API)(一次處理一個byte)(FileReader)
    • Filter: (加工的串流)(BufferedReader 可以一次讀取一行)(節省處理)

Notes:
  • 串流都是單行道, 讀資料使用來源的串流(source stream), 盡頭串流(sink stream)開啟輸出資料流
Notes:
  • filter 也稱加工的串流(Processing String)
  • 可以在網路傳送java的物件只要實作 Serializable介面

*Console I/O
  • System.out變數可以將資料輸出到系統的標準輸出端(standard output), 他是一個PrintStream型別物件
  • System.in變數可以從系統的標準輸入端(standard input)輸入資料, 他是一個InputStream型別物件
  • System.err變數可以將錯誤資訊輸出到系統的標準錯誤輸出端(standard error), 他是一個PrintStream型別物件


Notes:
  • e.printStackTrace();

Scanner API 提供格式化輸入的功能, 可以套用於console 以及檔案或是網路的串流.

Notes:
  • useDelimiter 設定切割符號
  • 關閉串流的動作是釋放系統的資源

*格式化輸出
  • 可以使用格式化(formatting)的功能如下:
    • System.out.printf(%s %d%n, "Ken",100)
      • %s 輸出字串(任何的資料都可以用%s來輸出)
      • %d %o %x 輸出整數 (, 10進位, 8進位, 16進位)
      • %n 為換行
      • %f %g 輸出浮點數 ()
      • 可以在前面加上數字指定長度, 例如 %10s 長度為10
      • %% 輸出%符號
      • %b 輸出 boolean
        • If the argument arg is null, then the result is "false". If arg is a boolean or Boolean, then the result is the string returned by String.valueOf(arg). Otherwise, the result is "true".
IllegalFormatconversionException 為指定的資料與型別不符(例如應該給整數卻給浮點數)

Mod15.java

package mod15;

import java.util.Date;

public class Mod15 {

public static void main(String[] args) {
int a = 100;
double b = 12.345;
String c = "Hello";
Date d = new Date();
//%30s --> output 30 characters
System.out.printf("%s%n", a);
System.out.printf("%s%n", b);
System.out.printf("%s%n", c);
System.out.printf("%s%n", d);
System.out.printf("%20.5f%n", b);
// 使用%b的時候, 如果值為null 輸出false, 如果是大小寫Boolean就看是true 或是 false來輸出, 如果是其他的型別但是值又不是null就會輸出true
String e = null;
Date f = null;
boolean g = true;
Boolean h = false;
int i = 100;
String j = "Hello";
Date k = new Date();
System.out.printf("%b%n", e);
System.out.printf("%b%n", f);
System.out.println();
System.out.printf("%b%n", g);
System.out.printf("%b%n", h);
System.out.println();
System.out.printf("%b%n", i);
System.out.printf("%b%n", j);
System.out.printf("%b%n", k);

}
}


*檔案和檔案I/O
  • 建立File物件
  • 操作File物件(對檔案本身進行操作, 例如重新命名或是刪除, 不對內容操作)
  • 讀取或是寫入檔案的串流(File streams)

何謂可序列化的資料(物件)?
  • 基本型別預設就是可序列化
  • 物件要可序列化必須符合
    • 其類別要實作java.io.Serializable interface
    • 類別屬性也一定要是可序列化的.

沒有留言: