[Java_note] 基本資料型態與參考資料型態


Posted by tzutzu858 on 2020-07-23

Java 中的變數 (variable) 有兩種 :

  1. 基本資料型態 (Primitive Data Types)
  2. 參考資料型態 (Reference Data Types)

基本資料型態(Primitive Data Types)共有八種

特性是變數值內容直接放在變數內

型態類型 關鍵字 位元數 範圍
整數 byte 8 -128 ~ 127
整數 short 16 -32768 ~ 32767
整數 int 32 -2147483648 ~ 2147483647
整數 long 64 -9223372036854775808 ~ 9223372036854775807
浮點數 float 32 依據 IEEE 754 標準
浮點數 double 64 依據 IEEE 754 標準
布林值 boolean 1 true, flase
字元 char 16 '\u0000' - '\uffff'

* 補充字元型態
由於 Java 支援 Unicode 編碼,因此任何 Unicode 字元都可以當作字元型態的的字面常數。字元型態的字面常數為單引號圍起來的單一字元,或是單引號圍起來,反斜線加上四位的十六位元數字,例如

char a = '\u0061'; // 小寫英文字母 a
char b = '\u0032'; // 阿拉伯數字 2

反斜線加上特定英文小寫字母表示跳脫字元,用來表示一些不可見字元,例如

char c = '\n'; // 換行符號
char d = '\t'; // tab 鍵

參考資料型態(Reference Data Types)

除了 Primitive Data Types 以外都是 Reference Data Types。

  1. 字串 (String)
  2. 陣列 (Array)
  3. 類別物件 (class object)

為什麼叫 Reference ,因為它們都是指向物件的參考,而參考資料型態在執行=運算式時,並不是複製整個資料,而是複製所指記憶體位置。而記憶體分成為三大區塊 :

Global 全域

主要放 :

  1. 全域變數(global variable)
  2. 靜態變數(static variable)。

全域變數(global variable) :
如果一個類別的成員變數有 static 修飾詞時,表示所有此類別的物件可以共享此 static 成員變數,不是每一個類別的物件都有一份各自獨立的成員變數,也因此又稱為全局變數(global variable)

Stack 推疊區

這個區域算是貧民區,必須設初值,另外兩個區 Global 和 Heap 系統會幫你初始化。
Stack 具備全自動化管理區塊,同時又具有存取速度快和管理簡單的特點,但要達到上述特點,代表生命週期可被預期並且按照 LIFO (Last-In-First-Out) 後進先出,也就是越晚產生的越先被回收或銷毀。如果 Stack 區不夠用或是遞回涵式(recursive function)沒寫好,會出現StackOverflowError 。
主要放:

  1. 基本資料型態(Primitive Data Types)
  2. 區域變數(local variable)
  3. 方法的參數(method parameter)
  4. 方法的回傳位址(method return address)等。

Heap 堆積區

和 Stack 相反, Heap 就放一些生命週期是不可預期,隨著程式執行記憶體越來越少,程式設計師必須自行管理此區的記憶體,但 Java 還是會採用 Garbage Collection (簡稱 GC) 垃圾回收這個機制去清理 Heap 內已經沒有被參考 (Reference) 的資料。若 Heap 區記憶體不夠用,會產生 OutOfMemoryError。
主要放 :

  1. Objects
  2. JRE classes

有了記憶體基本觀念後就要來看一下參考資料型態(Reference Data Types)會怎麼放,假設自訂一個類別叫 Animal 。這行 Animal dog = new Animal(); 程式要把它拆成兩部分來看,首先是Animal dog ,宣告了一個變數 dog,在 stack 區切一個參考(reference)大小的空間出來,這個參考(reference)預期會指向 Animal 物件,Java 會初始化內容為 null (指到沒有地方)。

再來 dog = new Animal(); ,new 透過建構子來建構物件,建構出來的物件放在 Heap 區,並透過指定運算子 =,把剛剛創造出來的物件在 Heap 區的位置指定給變數 dog。


String

當使用直接初始化創建 String 時,JVM 都會在 Heap 內存中檢查 String。
如果找到具有相同值的 String ,則指向剛剛創建好的新 String,(給它一個 String Pool 比較好理解)。但如果是使用新的構造函數(constructor)創建的(註一),則無論對像是否已經存在於 Heap 中,都將在 Heap 中重新分配新的空間。

由於字串是不可變(immutable)的,因此當你嘗試修改從 String Pool 創建的字串的值時,會從 String Pool 創建新的字串或引用。 String Pool 可幫助 Heap 存得最佳利用,因為在 Heap 上創建的字串越少。越能減少 Garbage Collection 的工作。


註一 : constructor 構造函數,或稱建構子,是一個類別裡用於建立物件的特殊子程式,它能初始化一個新建的物件,並時常會接受參數用以設定實例變數。建構子跟一般的實例方法十分相似;但是與其它方法不同,建構子沒有返回類型,不會被繼承,且不會有範圍修飾詞。建構子的函式名稱一般與它所屬的類別的名稱相同。 它承擔著初始化物件資料成員並建立類不變象的任務;在類不變象無效的時候它會失敗。一個正確編寫的建構子會使它生成的物件保持在一個有效狀態。不可變物件必須在建構子內完成所有初始化。

文章參考 :
String Pool | Java
那些字串二三事
深入理解Java中的不可變物件
基本與參考資料型態差異
Java Heap Space vs Stack










Related Posts

Javascript學習筆記04—條件運算式(Conditional Statements)

Javascript學習筆記04—條件運算式(Conditional Statements)

# 第一次夜訪鹽巴,就失敗

# 第一次夜訪鹽巴,就失敗

Day01 聊聊對話機器人與LINE Developers

Day01 聊聊對話機器人與LINE Developers


Comments