作者: 許裕永
l 變數名稱允許使用大小寫的英文字母,數字,底線符號(_)及貨幣符號($)來組合,但不可以用數字開頭。l 整數的預設型別為int,浮點數的預設型別為double。
l 整數值若大於int之最大或最小範圍,必須在值的尾端加上‘L’或‘l’。l 浮點數的值若要指派給float型別的變數,必須在值的尾端加上‘F’或‘f’。
l 字元資料總共有5種表示方式。l 布林值的true跟false,不能用數字的1跟0替換。
l 變數只存活宣告的程式區塊中。l 參考變數所代表的記憶體空間裏,儲存的不是資料,而是儲存一群資料的連續記憶體區塊的代號。
l 物件是指用new配置的連續記憶體區塊,區塊中儲存著資料。l 參考變數也可以稱之為物件名稱;參考變數可以參照到物件,也可以說參考變數代表物件,但參考變數(物件名稱)不是物件。
l long型別的資料可以自動轉換為float的型別。l 常數宣告時不一定要立刻指派,但只能指派一次
| 符號 | 意義 | 範例 |
| + | 求和 | a+b |
| - | 求差;負值 | a-b,-b |
| * | 求積 | a*b |
| / | 求商 | a/b |
| % | 求餘數 | a%b |
| ++ | 增量(加1) | a++,++a |
| ── | 減量(減1) | a──,──a |
| 符號 | 範例 | 同義敍述 |
| = | a=b | |
| += | a+=b | a=a+b |
| -= | a-=b | a=a-b |
| *= | a*=b | a=a*b |
| /= | a/=b | a=a/b |
| %= | a%=b | a=a%b |
|
符號
|
意義
|
範例
|
| == | 等於 | a==b |
| != | 不等於 | a!=b |
| > | 大於 | a>b |
| >= | 大於等於 | a>=b |
| < | 小於 | a<b |
| <= | 小於等於 | a<=b |
|
符號
|
意義
|
範例
|
| & | 長程 and | a<b & b<c |
| && | 短程 and | a<b && b<c |
| | | 長程 or | a<b | a<c |
| || | 短程 or | a<b || a<c |
| ! | not | !(a==b) |
流程控制
switch
l 區塊中的case沒有個數的限制,而且不必依照值的大小排列。
l case後方的值一樣必須是整數,且其值不可以超過運算式的最大或最小值的範圍。
l 區塊中所有case的值不可以重複。
l 因為case後面的值必須在編譯時期就確認,所以不可以是變數。
l case後面只能放數值或字元或在宣告時立刻指派的常數。
l 當switch中某一個case成立後,便會執行該case的敍述區,直到遇到break或這個switch的末端。
l default可以省略,也不一定要置於最末端。只不過若沒有置於最末端,就必須注意有沒有必要加break。
l default的敍述區,必須是在所有case均不成立的狀況下,才會執行。即使case置於default下面,也不例外。
l break和continue都是用來中斷撰寫該指令的迴圈。但在巢狀迴圈中,如果要中斷的對象是外圍迴圈時,便必須搭配標籤使用。而標籤必須宣告在迴圈的上方。
陣列
l new是一個指令,它命令Java配置記憶體區塊。中括號裏的值為陣列長度,必須是整數。配置完成的記憶體區塊,我們稱之為陣列物件。
l 陣列元素的序號,編列為0~(陣列長度-1)。
l 在配置記憶體區塊的同時,Java便已經將各資料型別的預設值,指派給所有的陣列元素了。
l 宣告敍述句後,可以用大括號直接指派陣列元素的值。但中括號中一樣不可以有數字,而指派值的個數,便是陣列長度。
l 一組中括號代表一個維度,中括號可分開置於資料型別或參考變數的後面,中括號的總數量,就是陣列的維度。
l 多維陣列建構時,至少要指定第一個維度的長度。
l 非基本資料型別的陣列物件,其陣列元素的預設值為null。
l java‧util‧Arrars,這個類別中,提供了一些運算一維陣列的方法。
l 參考變數‧length是取得第一個維度的長度,後面每加一組中括號就是取得下一個維度的長度。
字串類別
l 建構方法所扮演的角色:它是讓設計師用來建構某一個類別的物件時,所呼叫的方法。
l Java在程式碼中遇到用雙引號包的字串值時,便會自動依此字串值建構一個String類別的物件。
l 位於方法名稱前端的資料型別宣告,代表這個方法的執行結果的型別。若此型別為基本資料型別,代表方法的運算結果是一個該型別的值。若型別為類別名稱,則代表方法執行的結果為該類別所建構的物件。
l 參數宣告了本方法被呼叫運算時,一定需要的值或物件。
l 方法的呼叫可以用參考變數代表物件呼叫,也可以用物件直接呼叫。
l 物件建構時,如果是用new呼叫建構方法,那麼無論要建構的物件,String cnostant pool中是否已經存在,Java會均在一般的記憶體 中,建構一個物件。只不過,若String constant pool中沒有要建構的物件,那Java會另外建立一個一模一樣的物件置於String constant pool之中。
l 如果是用字串值直接指派的方式,而且指派的物件String constant pool中已經存在,Java便會將已經存在的物件的物件代號,指派給參 考變數,而不會再建構新的物件。但是,如果指派的字串值String constant pool中不存在,Java便只會在String constant pool中建構一個新的物件後指派其物件代號。而不會建構於一般的記憶體。
l 用關係運算符號的“==”比對兩個參考變數時,是在比對這兩個參考變數是否代表同一個物件。
l 若要比對的是物件的內容,則必須呼叫String類別中所提供的方法:equals(Object o)。
l 類別中宣告的所有方法成員,以運算的對象來區分,可以分為實體方法成員(instance member)及類別方法成員(class member)。
l 類別方法成員的運算和物件無關,所以也可以不必用物件(參考變數)來呼叫,可以用類別名稱直接呼叫。即使程式中並無該類別所建構的物件,一樣可以用類別名稱來呼叫該類別的類別方法成員。
l StringBuffer類別中修改物件內容的方法,均有宣告運算結果為StringBuffer物件,這並不表示說修改後的內容也有建構成新的StringBuffer物件。它代表的還是原物件。
l 若要比對兩個StringBuffer物件的值,必須以之建構String物件後,再用equals來比對。
Wrapper Classes
l parseXxx(String s)屬於類別方法成員,可以用物件名稱呼叫,也可以用類別名稱呼叫。Wrappers類別中除了Character外,各類別均有宣告此方法,用來把字串物件轉換為該類別對應的基本資料型別的值。
l Wrappers中的每個類別均有宣告valueOf(參數),但參數樣式不完全一樣。它也是類別方法成員,用來把參數轉換為該類別之物件。
l toString()是物件方法成員,可以用物件值建構一個字串物件。
l toString(參數)是類別方法成員,可以用參數值建構一個字串物件。
l Integer及Long這兩個類別均有宣告將參數值轉換為2進位、8進位及16進位值的方法。
l Double及Float這兩個類別均有宣告將參數值轉換為16進位值的方法。
AutoBoxing
1. 認證重點整理
l 物件或代表物件的參考變數置於運算式之中,編譯器會自動取得該物件的值,如同呼叫xxxValue()。
l AutoBoxing時,如果值佔用的記憶體大小,在一個byte之內,則此物件會建構在一個專屬的記憶體範圍,在這個範圍中的物件,會重複指派給需要相同值的參考變數。
l 用final宣告的參數變數,是限制儲存在參考變數中的物件代號不得變更,但不代表物件內容不能改變,所以該參考變數仍不能作為case後面的判斷值。
數字及日期的運算及格式化
l Math‧round(參數)的運算結果:參數四捨五入的運算。若參數型別為double則運算結果的資料型別為long;若參數型別為float則運算 結果的資料型別為int。請注意若參數值為負值時,其進位方式為-0‧1~-0‧5進位;-0‧6~-0‧9捨去。
l Math‧random()運算結果:大於等於0‧0而且小於1‧0的亂數。請注意,沒有等於1。
l 指派Date物件的日期時,年是以1900年為起點,月是以0為起點。
l add及roll的差異性。
l 取得及設定Date物件的應用。
l 類別常數成員的使用。
檔案管理與輸入輸出
l 建構File物件。注意事項有二:1、路徑分隔符號是‘/’,不是‘\’。2、若不是以磁碟機代號起頭,則預設為執行檔的所在位置。
l mkdir()與mdkirs的差異性。
l File類別的物件只能讓我們取得檔案的相關資訊,並不能讓我們取得檔案內容。
l 建構方法中,可以指定檔案內容的輸出方式。
l 四種緩衝類別物件的建構有一個特點:只接受輸入或輸出物件為參數,不可以用File物件或String物件為參數。
輸入與輸出的格式化
l matches()的檢測是包含樣式與字數都必須完全符合。
l compile(String regex)會依照String物件的樣式,來建構Pattern物件。請注意不是getInstance()。
l matcher(CharSequence input)會建構Matcher物件。
l 以File物件建構Scanner物件,就是開啟檔案來做為資料來源。相對的也請記得,讀檔完畢後應呼叫close()來關閉檔案。
l System‧in指的是java‧lang‧System類別中的類別常數成員in。它是一個InputStream類別的物件,用來接收鍵盤的輸入。 但是它提供read()一次只能讀一個字元,操作上不方便,所以本書中都利用它建構Scanner物件,來簡化接收鍵盤輸入的程式碼。
l 擷取部份資料時,應利用hasNext()搭配next(),才比較不會造成執行時期的錯誤。
l System‧out‧println();中的System‧out,指的是java‧lang‧System類別中的類別常數成員out,而out便是一個以PrintStream類別建構的物件。而輸出的目的地是螢幕。
l 用String物件代表檔案名稱,可以省略建構File物件的步驟,但也就沒有辦法指定是要以加入或覆蓋的方式輸出。
l 在printf()中的第二個參數寫的是Object‧‧‧,指的是任意個物件,也因為是物件,所以應該要用Wrapper Classes的類別建構的 物件。不過因為有Auto Boxing 及 unBoxing所以撰寫程式時,即使變數是用基本資料型別宣告也是可以的。另外,以運算式為參數也可以。
l printf()的String參數中設定格式的完整語法(中括號代表可以省略):
Exception 與 Assertion
l Exception是一個類別名稱,它底下有許多的子類別分別代表各種不同狀況產生的錯誤。
l 沒有撰寫錯誤處理,而程式一樣可以編譯的Exception屬於UnCheck Exception。
l 沒有撰寫錯誤處理,程式就無法編譯的Exception屬於Check Exception。
l 觀念:1、所謂產生Exception其實是建構了某一個Exception類別的物件。2、建立Exception物件的是Java。3、Exception物件會先傳回程式之中。
l catch區塊執行完畢後,並不會再回頭去執行try區塊中未執行的程式碼。
l Exception在catch中的排列,父類別要置於子類別下方。
l 我們應該要把跟try區塊中的程式碼有關聯,而且一定要執行的程式碼,寫在finally的區塊中。
l 如果變數a宣告在try的區塊中,那麼變數a就只存活在try的區塊,無論是catch或finally的區塊都不能存取。
l try區塊後可以直接寫finally,而不寫任何catch。
l 如同if跟for一樣,try catch也可以是巢狀的。
l try catch finall是整體,各個區塊之間,不可以撰寫任何敍述句。
例:try{
}
a++;
catch{
}
這樣會編譯失敗。
l 丟出Checked Exception的方式有兩種。第一種是:呼叫有宣告throws ChecdedException的方法,而該呼叫敍述沒有置 放於try catch的機制之中。另一種就是:在程式碼中用throw指定丟出的Exception物件。
l 方法中不想丟出去的Checked Exception應該自行用try catch處理。
l 方法中想丟出去的Checked Exception必須在方法名稱後面用throws宣告。
l throw可以丟出的Exception物件,不管是UnChecked或Checked的Exception都可以。只是,如果是Checked Exception就一定要宣告於throws的後面;但如果是UnChecked Exception則是否宣告於throws後方都可以。
l Assertion機制是讓設計師設定程式中斷點,來協助處理邏輯錯誤的機制。
l assert是在條件值為true時繼續執行,條件值為false時中斷程式。也就是條件值應該是設計師預期要的值,而當執行時期該值不符合設計師的期望時,中斷程式。
l Assertion機制在使用者執行時,是肯定關閉的,因為使用者不會去開啟它,也沒有必要。
l Assertion機制所產生的error是用來中斷程式,協助我們除錯,請不要把它當做另一種if的語法來寫,更不要用try catch的機制來補捉這個AssertionError。
l 不要在assert中執行必要的運算。
l 不要用Assertion機制來檢測public方法的參數。
l 不要用Assertion機制來檢測方法的運算結果。
l 建議使用Assertion機制來檢測private方法的參數。
l 建議使用在switch的語法中,來了解case不成立的原因。
類別開發
1. 認證重點
l 資料成員有預設值,而區域變數沒有預設值。
l 資料成員的預設值和陣列元素的預設值是一樣的。
l 物件可以透過成員存取運算子‘‧’來存取物件成員。
l 在Java的命名原則中,資料成員名稱,建議用小寫英文字母開頭。
l 運算結果型別指的是:方法的執行結果是否為一個值(物件)。如果是:就必須在方法名稱前宣告此值(物件)的型別(類別);如果不是:就必須在方法名稱前面宣告void。
l 參數列指的是:呼叫本方法時,必須傳遞過來給本方法運算用的值的型別,及其值在本方法中的名稱。
l 物件可以透過成員存取運算子‘‧’來呼叫方法成員。
l 如同用break來中斷switch或迴圈一般,方法也可以中斷,其關鍵字為return。
l 方法中沒有return,便會執行到本方法的最後一行敍述句後再返回。
l 如果現在設計的方法,是為了運算出(或取得)某一個值(物件),那麼這個方法的名稱前面便要宣告該值(物件)的型別(類別)。而且運算的結果必須置於return之後;
l 方法名稱前面若有宣告運算結果的型別,程式碼中就一定要把運算結果置於return之後。而且該return敍述一定要有機會執行。
l 參數指的是:本方法運算時會用到的,需要由呼叫敍述提供的值。而呼叫敍述句中所傳遞進來的值,便會置於參數列宣告的參數名稱之中。
l 參數列宣告的參數,屬於本方法的區域變數。
l 類別內部中,各個成員的彼此呼叫或存取,都不必透過任何媒介,可以直接呼叫(方法成員)或存取(資料成員)。
l 在Java中,參數傳遞的方式只有一種:把變數中的值複製一份,傳遞給參數。只不過若是參考變數,則傳遞的將是物件代號,也就會變成兩個參考變數指向同一個物件。
l 若是以參考變數當參數,就必須注意物件值有被更改的可能。
l String及Wrapper Classes中的類別宣告的參數變數,用‘=’指派新值時,新是建構新的物件。也是說這些類別建構的物件的值,是不能改變的。
l 宣告類別為本方法運算結果的型別時,可以在return後加上null。代表空值。
l 呼叫Var-args的方法時,給的參數是任意個參數,當然也可以沒有參數甚至可以用陣列當參數。
l Var-args宣告符號“‧‧‧”必須置於宣告型別之後,不是參數名稱之後。
l Var-args宣告的型別可以是基本資料型別,也可以是參考資料型別。
l 參數列中除了Var-args外,也可以宣告其他參數。
l 參數列中只能有一個Var-args樣式的參數。
l 參數列中的Var-args必須置於最後面。
l 方法的命名原則基本上和資料成員一樣,用小寫英文字母開頭,第二個英文單字再以大寫英文字母開頭串聯。但是有一點要特別強調的是:設計存取資料成員的方法時,一樣依照這個原則命名。
l 在程式執行初期,Java會先載入,所有本程式中有使用到的類別。在載入的同時,便會配置記憶體給所有的類別資料成員,並給予初值。
l 無論是,在該類別還沒有建構任何物件之前,或所有建構的物件都已經被消毀,一樣可以用類別名稱,來存取類別資料成員。
l 整個程式的執行期間,該類別資料成員所佔用的記憶體空間並不會改變,所以不管是用類別名稱,或是用物件,存取的都是同一個記憶體空間的值。
l 若類別資料成員的值記錄著共用值,且不希望被變更,可以用final宣告為類別常數成員。而此種類別常數成員的命名,一般均以大寫英文字母搭底線符號。
l 方法宣告句的運算結果型別前端,加上static,便是宣告本方法為類別方法成員。類別方法成員可以讓類別名稱呼叫,也可以讓物件呼叫。
l 類別方法成員有一個非常重要的注意事項:方法中不可以存取實體資料成員或呼叫實體方法成員。
l 參數列的個數或參數的位置或參數的型別,任何一個不完全一樣,都可以是Overloading。而且運算結果的型別也可以不一樣。
l 對於基本資料型態的值,Java會自動轉換參數值來呼叫合適的方法。
l AutoBoxing機制在方法呼叫時,無論是參數列,或是運算結果型別,都是適用的。
l 如果沒有符合參數型別的方法,Java會自動把Warpper Classes的物件以Auto Boxing或 UnBoxing的方式轉換為適當的參數值,來呼叫方法。
l 基本資料型別自動轉換的執行,優先於AutoBoxing。
l 參數列完全符合的執行,優先於Var-args。
l 參數列基本資料型別自動轉換的執行,優先於Var-args。
l AutoBoxing的執行,優先於Var-args。
l 類別中如果沒有自行撰寫建構方法,編譯器會自動替我們產生一個不需要參數的建構方法。
l 若設計師在類別中,撰寫了任何一個建構方法,編譯器將不再提供預設的建構方法。
l 建構方法可以利用Overloading機制,提供使用者多樣化的參數列變化,來建構該類別物件。
l 因為this代表執行方法的物件,所以程式碼中也就可以用“this‧成員”的寫法,來存取或呼叫所有的成員了。
l 因為this是代表物件,所以它不能在static的方法之中使用。
l this(參數),只能寫在建構方法中的第一行,用來呼叫本類別的其他建構方法。
l class的宣告句前端加上final表示本類別不可以繼承。
l 常數的宣告,適用於實體資料成員,類別資料成員,還有區域變數。
l 用final宣告的參考變數,只能建構一次,然後儲存於此參考變數中的“記憶體位址”便不能改變。但是,物件的值是可以改的。
l 參數列中的參數也可以宣告為final,其特性和final variable是一樣的。
l 方法宣告時,在方法型態的位置宣final,表示本方法不接受Overriding。
l 類別方法成員(static)也不可以是abstract。
l 請注意宣告抽象方法時,因為抽象方法代表尚未定義的方法。所以:方法宣告完畢必須用‘;’結束,不可以加“{}”。
l 抽象方法沒有定義,那它的存在是為什麼呢?它是用來讓子類別繼承後定義的。換個角度來看,就是限定子類別一定要定義這個方法。
l 類別型態宣告為abstract者,代表為抽象類別。抽象類別不可以建構成物件,也就是不能實體化的意思。注意:即使有撰寫建構方法,也不能建構成物件,但是撰寫建構方是合法的。
l 抽象類別中不一定要有抽象方法。
l 擁有抽象方法的類別一定要宣告為抽象類別。
l 參數的傳遞是將文字以空白區隔,置於檔案名稱後方,個數沒有限制。
l 命令列中置放於啟動類別名稱之後的字串值,會建構成String物件陣列,傳至main方法中的參數args。但是若沒有字串值,也一樣會傳入String物件陣列給args,只不過其陣列長度為0。
l 類別初始化區塊只在類別載入(第一次執行)時依序執行。
存取限制
l package是部署類別的單位,也是一個置放class檔的資料夾,也是類別名稱的一部份。
l package的宣告,就是在開發類別的時候,直接指定本類別的部署位置,也就是置放本類別class檔的資料夾名稱,也就是要存取本類別時,必須加註在類別名稱前面的package名稱。
l package名稱命名時,建議以小寫英文字母開頭。
l package的宣告一定要置於程式碼檔的第一行。
l classpath設定注意事項:1、可以設定相對路徑或絕對路徑。2、可以用‘;’區隔,設定一個以上的路徑。3、路徑的層次符號為:‘/’。4、設定的路徑,是置放package的資料夾,不要連package的名稱都設定進去。
l import宣告時注意事項:1、本宣告句必須置於package宣告之後,class宣告之前。2、本宣告句可以引用一個class,也可以用*代表該package中的所有class。3、
‘*’只能代表類別,不能代表子package。
l 在類別宣告時,類別名稱前可以用存取限制詞public,來設定本類別是否允許不同package的類別存取。
l public宣告注意事項:1、class的存取限制詞,只有一個public。差別是有宣告和沒有宣告。請不要在類別名稱前面宣告其他的存取限制詞。 2、一個程式碼檔中(java檔),可以開發一個以上的class,但是只能有一個是public,而且檔案名稱必須和該宣告為public的類別名稱相 同。
l 用static imports的機制,只引入指定類別中的類別成員。
l 成員存取有下列三種:1、用類別名稱存取類別資料成員或用類別名稱呼叫類別方法成員。2、用物件存取實體資料成員或呼叫實體方法成員(物件也可以存取或呼叫類別成員)。3、在子類別中,存取父類別的資料成員或呼叫父類別的方法成員。
l 在開發類別的時候,類別中所有的成員,彼此的呼叫或存取,是完全沒有限制的。
l 宣告為private的成員,不接受類別使用者用任何模式呼叫。只允許類別開發者,在撰寫類別中的程式碼時,呼叫或存取。
l 把重要的資料成員宣告為private,讓外界無法直接存取,甚至不知道也不必知道它的存在,這叫做「資訊隱藏」。
l 不必讓使用者知道所有你設計的成員,只要公開那些接受使用者存取或呼叫的成員。這樣的行為叫做「封裝」(Encapsulation)。
l 父類別中設計寬鬆,各個子類別,便能依各自需求來設計從父類別繼承過來的成員,如此可以增加設計上的彈性,專業詞叫「降低依存性」(loosely coupled)。
l default不是一個用來宣告的關鍵字。它是指,如果成員宣告句前方,並沒有放置任何存取修飾詞的時候。這個時候預設的存取限制為:package。
l 宣告為package存取限制的成員,在同一個package的其他class中,可以任意的使用成員存取的三種模式來存取。但是,只要不是同一個package的class,就完全不接受存取(即使是子類別)。
l protected的宣告,對同一個package的類別而言,其限制和default是相同的。
l 宣告為protected的成員,是允許其他package的子類別繼承後,在子類別中存取。但是不允許建構成物件後,用物件存取。
l protected的宣告是針對不同package的class才有效用。
l 在子類別中,以物件呼叫成員的方式存取宣告為protected的成員,是不合法的。
l 要存取不同package的類別,必須該類別宣告為public,而且要import。
l 宣告為public的成員,完全沒有限制,不管是否在同一個package,均可以任意使用三種存取模式存取。
l 預設的建構方法其存取限制和類別一樣。
Object類別與繼承
l 任意物件,只要是在需要轉換為字串的運算式之中,Java都會自動呼叫該件的toString()。
l 任何類別從Object繼承來的equasl(),其預設的功能都是用來比對是否為同一個物件,也就是和“==”的比對方式是一樣的。
l hashCode()的運算結果是一個代表本物件的整數值,它是Java執行內部運算時,識別物件的依據之一(例:集合物件中,用來排序的依據)。如果此方法的運算結果和Java期望的不一樣,可能會造成某些運算的錯誤。
l 類別繼承了父類別中的所有成員,只是並非所有成員都可以任意存取。
l 父類別中宣告為private的成員,子類別有繼承,但是不能存取。
l 父類別中宣告為protected的成員,不同package的子類別,可以在類別中以直接存取的方式存取,但是不能建構成物件之後以物件存取,同一個package的子類別可以用任意方式存取。
l 父類別中宣告為public的成員,子類別中可以用任意方式存取。
l 父類別中未宣告存取限制的成員,同一個package的子類別可以用任意方式存取,不同package的子類別中,不可以存取。
l 本類別建構的物件,呼叫方法的時候,執行的是本類別中自行定義的內容。
l 但是overriding是有取代性的,定義的新內容會取代舊的內容。而且只能運用在子類別overriding父類別的方法。
l overriding的方法名稱必須相同。
l overriding的運算結果型別若是基本型別 ,必須完全一樣。
l overriding的運算結果型別若是類別,可以是其子類別。
l overriding的參數列無論是個數或型別,必須完全一樣。若稍有不同,即為overloading。
l overriding的存取限制修飾詞,可以一樣或更寬鬆,但是不可以更嚴格。
l overriding的方法throws的Exception的個數,可以一樣或比較少,但是不能更多。(Checked Exception)
l overriding的方法throws的Exception,可以是父類別throws的Exception的子Exception,但不可以是父Exception。(Check Exception)
l 不可以overriding父類別中宣告為final的方法。
l 沒有辦法overriding父類別中宣告為static的方法。
子類別中的類別方法成員的名稱,可以和父類別中的類別方法成員的名稱一樣。但這不是overriding。因為這些方法是屬於類別,不屬於物件,和物件無關。
l 不可以overriding父類別中宣告為private的方法。
l 子類別繼承了一般類別之後,是否overriding父類別的方法,可以自行決定。但是,若繼承了抽象類別,則是一定要overriding抽象方法。也就是說:抽象類別規範了子類別一定要定義的方法。
l hashCode()的運算結果只要是int值,編譯便合法,但卻不見得符合Java的期望。
l 若兩個物件,用equals比對的結果為true時,其執行hashCode()的運算結果一定要相同。
l 若兩個物件,執行hashCode()的運算結果不相同時,則它們用equals比對的結果必須為false。
l 若兩個物件,執行hashCode()的運算結果相同時,則它們用equals比對的結果並不一定要true。
l 若兩個物件,用equals比對的結果為false時,其執行hashCode()的運算結果完全沒有理會的必要。
l
l 子類別的建構方法中,即使沒有指定呼叫父類別的建構方法,Java也會預設呼叫父類別的建構方法。
l Java預設呼叫的是沒有參數的父類別建構方法,如果父類別中沒有沒參數的建構方法,就會造成編譯錯誤。
l 指定呼叫父類別的敍述句一定要置於第一行。
l 任何類別的建構方法中,第一個執行的敍述句,一定是呼叫父類別的建構方法(super()),或呼叫本類別的建構方法(this())。
l 用super‧資料成員,也可以存取父類別中被子類別覆蓋的資料成員及方法成員。
l 無論類別或實體初始化區塊,都是先執行父類別的區塊。
l 父類別的建構方法執行完畢之後,才執行子類別的初始化區塊。
界面
l 界面預設就是abstract。不加是抽象,加了也是抽象,加或不加都合法。
l 界面不可以是final。
l 不論宣告句中是否有修飾詞,interface中的資料成員就一定是public、static及final。
l 因為資料成員是final,所以宣告時必須立刻指派初值(物件)。
l 論宣告句中是否有修飾詞,interface中方法成員就一定是public及abstract。
l 界面可以多重繼承。也就是說,界面可以用extends來繼承一個以上的父界面。
l 類別繼承類別,界面繼承界面,是不可以亂繼承的哦!
l 界面中的方法,全部都是抽象方法,一定要全部overriding。否則,不要說建構成物件,連類別都要宣告為抽象類別。
l 類別中overriding界面的方法時,存取修飾詞必須(一定要)宣告為public,如果不宣告其預設限制為package,將違反overriding的規則,造成編譯錯誤。
物件多型及序列化
l Java中的所有物件,至少都擁有兩種型別:建構該物件的類別型別及Object型別。
l 開發一個類別實作界面後,再建構成物件,則此物件便擁有實作界面的型別。
l 子類別物件一定擁有父類別型別,但是父類別物件不可能擁有子類別型別。
l Is a指的是類別與類別的繼承關係。
l Has a指的是類別和類別的隸屬關係。
l 將子類別建構的物件,指派給父類別宣告的參告變數,則該物件將會自動轉換為父類別的型別。
l 子類別物件也可以指派給以父類別宣告的參數,來呼叫方法。
l 將向上轉型為父類別型別的物件,再轉回原來的型別,稱之為向下轉型。
l 向下轉型除了可以轉回物件的建構類別型別,也可以轉成建構類別的父類別型別,但不可以轉成建構類別的子類別型別。
l 為了避免執行時期發生錯誤,在向下轉型之前,我們會用instanceof這個運算符號來確認物件與類別的關係。
l 轉型的是物件,不是參考變數。參考變數的型別就是宣告的型別,不可以改變。
l 參考變數只是代表物件,不是物件。但是我們可以隨時指派任何型別符合的物件給它代表。
l 物件只能執行合乎當時型別的方法。而呼叫方法的是參考變數,所以:參考變數只能呼叫其宣告類別中的方法。
l 只要呼叫的方法,是符合參考變數型別的方法,該方法便可以執行,但執行的是,實際建構物件的類別中,定義的內容。
l
l 任何類別只要用implements宣告此界面,不必overriding任何方法,此類別建構的物件便擁有序列化的功能。
l 執行物件輸出這個功能的物件,是ObjectOutputStream類別的物件。
l 要被writeObject()輸出的參數物件須要有序列化的功能。
l 執行物件輸入這個功能的物件,是ObjectInputStream類別的物件。
l readObject()的運算結果型別是Object。也就是這個方法取得的是Object型別的物件,必須向下轉型後才可以指派給子類別宣告的參考變數(物件多型)。
l 實作serializable的類別,要注意資料成員的宣告。若類別擁有無序列化功能的資料成員,將會造成執行時期錯誤。
l transient譯為暫時性的。意謂著,用此修飾詞宣告的資料成員不必持續記錄,於是物件輸出時便不會輸出此資料成員的值。
l 宣告為transient的資料成員,輸入時便會指派預設值給該成員。
l 在序列化輸入時,只要有實作序列化界面的類別,它們的建構方法都不會執行。
l 如果實作序列化界面的類別的父類別,沒有實作序列化界面,則父類別的建構方法將會執行。
l 宣告為static的資料成員,並不在序列化輸入及輸出的範圍,因為它們不屬於物件。
內部類別
l 外部類別的任何實體方法成員中,均可以建構內部類別物件。
l 必須先建構外部類別物件,並透過此外部類別物件才能建構內部類別物件。
l 內部類別中,“this”指的是本類別物件;“外部類別名稱‧this”指的是外部類別物件。
l 必須注意宣告及建構的順序,也就是程式敍述句排列的順序。如同其他區域變數一般,必須先宣告再建構。
l 方法中的類別,也可以在類別中存取或呼叫外部類別的任意成員(即使宣告為private的成員)。
l 不可以存取方法中宣告的區域變數,除非該變數宣告為final。
l 此類別只能使用一次,也就是只能建構一個物件。
l 匿名類別,是開發某一個類別的子類別,或開發實作某一個界面的類別。但是,沒有辦法既繼承類別又實作界面。
l 撰寫時是為了方便程式碼的閱讀,才會分成數行文字,但一定不要忘記,敍述句是以‘;’結尾。
l 實作界面的匿名類別的物件和建構子類別物件有兩大差異:1、沒有參數列(要保留小括號)。2、要overriding InterfaceName中的所有方法。
l 不是一定要把物件指派給參考變數,也可以把物件直接當參數使用。
l 不可以宣告建構方法。
l 不能加任何修飾詞。無論是final,abstract,static,或存取限制修飾詞。
l 沒有必要宣告任何子類別的新成員。
l 任何外部類別的實體方法成員(abc()),均可以存取Static Nested Classes。
l Static Nested Classes中宣告的成員,不一定要是static成員。
l 在其他類別建構Static Nested Classes物件時,只需要用外部類別的名稱來呼叫其建構方法,不需要先建構外部類別物件。
l 不可以使用代表本類別物件的this。
執行緒
l 開發實作Runnable界面之類別,也可以overriding run()。
l Runnable界面並沒有完整的執行緒功能,所以Runnable型別的物件不算是執行緒物件。但是,可以用Runnable型別物件當參數,呼叫Thread的建構方法,來建構執行緒物件。
l start()是Thread中的成員方法,用來啟動執行緒。
l 多執行緒的程式,就是多個執行緒互搶執行權。
l Java也會把main建成一個執行。
l 同一個等級代號的執行緒物件可以有很多個,所以不是設為最高等級的物件就一定會最優先執行。
l 程式中可以用setPriority(int newPriority)來設定執行緒物件的優先等級。
l 執行中若把本執行緒物件的優先等級設成比目前更低的值時,本執行緒物件會暫時停止執行,直到其他優先等級較高者執行完畢,才會執行。
l sleep()是讓執行緒物件暫停,而且暫停的時間可以自訂,可以用毫秒,也可以用毫微秒。
l sleep()設定的時間,是執行緒至少暫停的時間,而不是最多暫停的時間。
l 我們寫run()時,其實是在overriding,所以sleep()宣告的InterruptedException物件,一定要用try catch處理,不可以用throws宣告在run()後面。
l yield()讓出執行權。它沒有指定時間,也沒有改變優先等級,所以用這個方法讓出執行權的執行緒物件,還是會加入搶執行權的行列。總之這個方法並不保證執行緒物件會暫停。
l join()是指定另一個執行緒物件執行完畢之後,本執行緒物件再執行。方法中也可以指定時間,表示指定另一個執行緒物件執行完畢或執行某一段時間之後,本執行緒物件再執行。
l 執行join()的執行緒物件,在指定的執行緒物件執行完畢或執行了指定了時間之後,本執行緒物件並不是立刻執行,而只是加入搶執行緒的行列。
l 被指定的執行緒物件,並不是就擁有最高優先等級而可以持續執行。這個方法只是暫停本執行緒物件的執行,而指定的執行緒物件還是得和其他執行緒物件搶執行權。
l 在Java中每個物件都有一個標記(flag),執行緒在執行synchronized區塊的程式碼之前,要先取得小括號中這個物件的標記,取得後開始執 行synchronized區塊。而其他執行緒,就必須等待執行中的執行緒物件,執行完synchronized區塊之後,釋放該物件的標記,才能接著取 得該物件標記,再執行synchronized區塊。
l synchronized的小括號中,不一定要是this,而是要與執行緒物件同步化的物件,但一定要是物件,不可以是一般變數。
l
l 當wait()執行時,本方法便會解除與執行緒物件之間的同步化鎖定(釋放物件標記),然後執行緒物件便暫停執行,乖乖的在等待池中靜候通知。
l 等待池中的執行緒物件,在等待的物件執行notify()之後,執行緒物件便可以繼續同步化執行。
l wait()及notiry()都是Object中的方法,也就是每個物件都有的方法。
l wait()有三式,可以指定時間,若時間已到卻還沒有接到通知,也會繼續執行。而三式都會throws InterruptedException。
l 通知有兩種:notify()及notifyAll(),後者用來通知所有等候本物件通知的執行緒物件。
集合與泛型
l Set這個界面的特色,便是對集合中的物件沒有建立識別系統。
l Set集合物件中的元素值不能重複。
l Set沒有辦法取得集合中某一個指定的元素。
l Set可以新增null,但只能一個,因為值不能重複。
l HashSet對於集合中的元素是以預設方式排列,也就是不會依照加入的順序排列。
l LinkedHashSet集合物件中的元素,是以新增的順序排列,也就是先進先出。
l TreeSet集合物件中的元素會從小到大自動排序。
l 因為TreeSet集合物件有自動排序功能,若集合物件中的元素無法比較大小時,便會產生錯誤訊息。
l TreeSet集合物件中若新增null為元素,亦會造成執行時期錯誤(因為無法比較大小)。
l 字串排序比對方式:1、以字元碼比對。2、由左向右逐字元比對。
l List中是可以置入equals()比對值為true的元素的。
l LinkedList集合物件中的元素,會以新增的順序或指定的位置排列。
l 指定的序號若超出List物件大小,將會造成執行時期錯誤。
l Vector支援執行緒同步化,也就是這個類別的所有方法均宣告為synchronized。
l LinkedList除了實作List界面之外,也實作了Queue界面。
l LinkedList類別建構的物件,可以執行List的方法,也可以執行Queue的方法。
l PriorityQueue提供了,List的所有類別所做不到的功能:自動排序。而且它的排序方式還可以自訂。
l PriorityQueue集合物件就是用Comparator物件來執行自動排序。Comparator是一個界面,裏面有兩個方法,一個叫 compare,另一個叫equals,自訂的排序準則便寫在compare之中,這個方法的運算結果分為負值、0及正值,分別代表小於、等於及大於的關 係。
l
l 做為識別代號的物件我們稱之為key,它必須是唯一的。
l HashMap以預設方式排列key(同HashSet),也就是key的排列方式與新增順序無關。
l LinkedHashMap以加入的順序排列集合物件中的key。
l TreeMap集合物件會將key之值自動排序。
l Hashtable物件中元素的排列方式和HashMap是一樣的。它最大的特色,是和List中的Vector一樣,支援執行緒安全。
l java‧util‧Collections這是一個類別,不是之前的Collection界面。這個類別的功能與java‧util‧Arrays相似,提供相當多的類別方法成員,來協助我們運算集合物件。
l 在宣告集合物件的參考變數時,於類別名稱後方加上“<型別>”,搭配建構方法的小括號之前加上的“<型別>”,即表示本集合物件只接受指定型別的物件。
l 在集合物件中取得的任意元素,不必向下轉型即為泛型中宣告之型別。
l 類別宣告時的“<A>”表示本類別可以接受泛型機制,‘A’只是一個代號,方便類別中的方法搭配宣告,要叫什麼都可以。
l 方法中的代號必須和類別搭配。
l 若方法的參數是集合物件時,可以使用:「1、<?>代表所有型別。2、<? extends E>代表所有E型別的子型別」,來宣告該集合物件參數,可以接受的泛型型別。
l 宣告泛型的類別所建構的物件是多型的。
l 泛型宣告的型別也是適用多型機制的。
列舉物件與垃圾收集
l enum是一個宣告列舉類別的關鍵詞,Java編譯器會以背景作業方式建立繼承Enum類別的子類別,並建構類別中的列舉物件。
l 我們可以像開發類別一樣,在eunm中,宣告及定義資料成員、方法成員及建構方法。
l enum中的類別常數成員宣告完畢後,必須上‘;’,才可以開始自訂其他的成員或方法。
l 若自訂有參數的建構方法,enum中的類別常數成員在宣告時,必須用小括號提供建構方法參數。
l enum中自訂建構方法的存取限制,若宣告為public將無法編譯。
l switch支援enum成員的判斷,判斷時便是自動呼叫該成員的ordinal()來取得整數值。
l enum也可以宣告在類別之中,成為內部類別,但是不可以宣告在方法之中。
l 宣告為內部類別的enum,預設為static。
l 執行環境會依照程式執行的狀況,找到適當的時機,再把記錄於垃圾集合件中的物件代號所代表的所有物件,全部銷毀。
l 適合被回收的物件只有一種:沒有參數變數儲存其物件代號的物件。
l 物件建構之後,沒有把物件代號指派給參考變數的物件。此類物件在其執行完該行敍述句後,便會被記錄於垃圾集合物件之中。
l 把B物件之物件代號,指派給原先儲存A物件代號的參考變數,而A物件已經沒有任何參考變數儲存它的物件代號時,A物件便會被記錄到垃圾集合物件之中。
l 指派null給原先儲存A物件代號的參考變數,而A物件已經沒有任何參考變數儲存它的物件代號時,A物件便會被記錄到垃圾集合物件之中。
l 一個被孤立的物件群組,會全部被回收。
l 呼叫類別System中的類別方法成員gc(),可以強迫Java執行環境立刻執行物件銷毀的動作。
l 建構RunTime物件,執行其實體方法成員gc(),可以強迫Java執行環境立刻執行物件銷毀的動作。
沒有留言:
張貼留言