<<1-5-4>>
變數的宣告Java 有兩種型態的變數:
- 基本資料(Primitives):有 8 種,分別為 char、boolean、byte、short、int、long、double 和 float,宣告後型別無法改變。
- 參考變數(Reference variables):是用來指涉(refer to,或存取到)到一個物件,一旦宣告成某型別後,就不能更改。一個參考變數可以用來指涉到任何其宣告型別,或宣告類別的子型別(subtype,一個相容的型別)的物件。
基本資料的宣告和範圍
- 基本資料變數可以被宣告成是類別變數(靜態的)、實體變數、函式參數或區域變數。
- 可在一行程式碼內同時宣告一個或多個同樣基本型別的基本資料,例:int x, y, z;。
- 整數型態的基本型別所代表的範圍從小至大順序為:byte, short, int, long。
- 浮點數的型態則是 double 比 float 大。
- 數字型態都是帶有正負號的(signed),最左邊的位元(最大有效位元,the most significant digit)被用來表示正負號,1 是負號,0 是正號,其它的位元則使用二系補數表示法(two's complement notation)來表示數值。
- 數字基本資料的範圍,只須記住前三欄即可。
Type Bits Bytes Min. Range Max. Range byte 8 1 -27 27-1 short 16 2 -215 215-1 int 32 4 -231 231-1 long 64 8 -263 263-1 float 32 4 n/a n/a double 64 8 n/a n/a - 多少位元可代表一個 boolean 值,是由虛擬機器決定的。
- 一個 char 型別的變數是使用 2 Bytes(16 bits)表示,因此可儲存 unicode 字元。其實 char 是一不帶正負號的(unsigned) 16 位元的整數來表示,可存放 216 的值,範圍為 0 至 65535 (216-1)。
宣告參考變數(Reference Variables)
- 參考變數可以被宣告成靜態變數、實體變數、函式參數或區域變數。
- 可以在同一行程式碼內,宣告一個或多個同型別的參考變數,例:String s1, s2, s3;。
實體變數(Instance Variables)
- 實體變數是被定義在類別內,但在任何函式之外,而且只有在一個類別被實體化的時候,才會進行被始化的動作。
- 實體變數是屬於每個獨一無二的物件的資料欄(fields)。
- 實體變數(Instance variable)又可稱為資料欄(field)或屬性(property/attribute)。
- 實體變數必須知道的規則:
- 可使用任何四種存取等級(public, private, protected 或預設)。
- 可以被標示成 final, transient。
- 不可被標示成 abstract, synchronized, strictfp, native。
- 另外也不可標示為 static,因為一旦標示為 static,它就變成了類別變數(class variables,或稱靜態變數)了。
- 區域變數、實體變數和函式的差異表(可宣告的修飾子):
區域變數 變數(非區域) 函式 final final
public
protected
private
static
transient
volatilefinal
public
protected
private
static
abstract
synchronized
strictfp
native
區域(Local,自動 Automatic / 堆疊 Stack / 函式)變數
- 區域變數就是宣告在函式內部的變數,非該函式的程式碼不可存取該區域變數。
- 區域變數在函式內部開始它的生命,在函式結束時,區域變數也會被銷毀。
- 區域變數一定是存在堆疊(stack)內,而不是在堆積(heap)內。
- 假如該區域變數是一個物件參考,則區域變數還是存於堆疊,而這個物件就會在堆積內被建立出來。所以並沒有存在一個叫做堆疊物件(stack object)的東西,只有堆疊變數。
- 所謂的區域物件(local object),指的是區域宣告的參考變數(local declared reference variable)。
- 區域變數只可使用 final 修飾子。
- 使用區域變數之前,必須先用一個值來初始化它,因為區域變數沒有預設值(實體變數有預設值)。
- 區域變數的名稱,可以與實體變數相同,這個方法稱為遮蔽(shadowing)。當發生此情形時,該函式要存取同名稱的實體變數時,要加上 this 關鍵字,例:
class Foo {
int size = 27;
public void setSize(int size) {
this.size = size;
}
}
陣列宣告
- 在 Java 中,陣列是一個物件它可以儲存數個同型別的變數,或同型別的子類別們的變數。
- 陣列可以被用來儲存基本資料或是物件參考,但即使這個陣列是被宣告來儲存基本資料,陣列本身永遠是堆積裡的一個物件。
- 建立一個陣列的參考變數:
- 宣告一個基本資料的陣列
int[] key; //建議方式
int key []; //合法但可讀性較低 - 宣告一個物件參考的陣列
Thread[] threads; //建議方式
Thread threads []; //合法但可讀性較低 - 也可宣告多維陣列(multidimensional arrays),其實它就是陣列的陣列,例:
String[][][] occupantName;//三維陣列宣告
String[] ManagerName []; //合法的二維陣列宣告,但寫法不好 - 在宣告陣列時同時宣告陣列的大小是不合法的,例:
int[5] scores; //此程式碼無法編譯
Final 變數
- 如果使用 final 這個關鍵字來宣告一個變數,一旦該變數已經被特定的值初始化了(而不是預設的),就不能再次初始化它。
- 對於基本資料,只要讓變數被指派了一個值,就不能再被改變。
- 對於物件參考變數(object reference variable),就是不能重新指派它去指涉到另外一個物件,不過讓物件的資料可以被修改,不能被變更的是參考變數。
- 沒有 final 物件,只有 final 參考。
- final 的應用意義:
物件(class) | final 類別不可被繼承 |
函式(method) | final 函式不可被子類別覆寫 |
變數(variable) | final 變數,一旦初始化後,就不能再指派新值 |
Transient 變數
- 假如將某類別的實體變數標示成 transient,就是告訴 JVM 在序列化(serialize)包含它的物件的時候,就要忽略它。
- 序列化是讓你可以儲存(有時候稱為”平坦化(flattern)”)物件的狀態(換句話說,該物件的實體變數的值)到一個 I/O 資料流(stream)上。使用序列化,可以將物件儲存到檔案上,或讓它在網路上傳送,並在另外一端的 JVM 上回復成原物件(再膨脹化(reinflating),反序列化(deserializing))。
Volatile 變數
- volatile 修飾子告訴 JVM,當一個執行緒存取了該變數,必須將執行緒本身對於該變數的私自拷貝版和記憶體內的主要拷貝版進行一致化的動作。
- volatile 就像 transient,是一個只可以應用在實體變數的修飾子。
Static 變數和函式
- 如果類別內的某些函式或變數,和該類別的任何實體是無關的,就可以應用 static 修飾子來建立這些函式或變數。
- 在建立任何該類別的實體之前,static 成員就已經存在了,而且不論類別有少個實體,這些 static 成員都只有一份,也就是所有實體共享同一份 static 成員。
- 可被標示成 static 的東西有:『函式』、『變數』、『一個包含在另一個類別內的類別(巢狀類別,nested),但不是在函式內的』和『初始化區塊(Initialization blocks)』。
- 不可被標示成 static 的東西有:『建構子』、『類別』、『介面』、『函式內的區域內隱類別(method local inner classes)』、『內隱類別的函式和實體變數』和『區域變數』。
沒有留言:
張貼留言