iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

今天要繼續講到參考類型的資料
如果忘記基本型態的部分可以回前一天看喔!

那我們就開始吧!

參考資料型態的宣告及給值: (假設有個自訂類別Human)

Human tina;
tina = new Human();

記憶體配置圖:
https://ithelp.ithome.com.tw/upload/images/20230920/201631399qhbOJDu83.png

讓我們來了解一下上面兩段程式碼做了什麼事

程式剛開始執行,記憶體沒有變數,

Human tina; 宣告了一個變數tina,會在stack區切一個參考(reference)大小的空間出來,這個參考(reference)預期會指向Human物件,Java會初始化內容為 null (指到沒有地方)。

tina = new Human(); 這個敘述分兩部份看:

第一部份: 關鍵字 new 透過建構子來建構物件,建構出來的物件會放在 Heap 區。

第二部份: 透過指定運算子「=」,把剛剛創造出來的物件在Heap區的起始地址,指定給變數tina。

這就是為什麼,參考型態的類別需要 new 才能使用,如果沒有在Heap區佔有真實物件的資料,那它在Stack區就只是一個參考(reference)而已,而且預設為 null,若存取到 null 的物件變數,會出現NullPointerException 的例外,這也是常見的程式錯誤。

Java並沒有指標(pointer)的概念,在Java稱為『參考(reference)』,為了改善c/c++指標理解、操作不易的問題,全盤捨棄指標改用參考。

String 字串

字串String可以代表字元的串列,例如 "abc" 就是一個字串類別的實體。

初始化字串:

String類別身為參考資料型態,一樣必須實體化才有資料,而String的實體化方式非常自由。

String str = "abc";

利用兩個雙引號『" "』夾起來的字元就會在Heap初始化物件產生空間,回傳reference給String變數。

字串有一個重要特性:「Immutable」,意即當「字串」 一經生成,便不能改變。

String str = "A";
str += "B";
System.out.println(str); // AB

打印的結果是字串:「AB」,而「AB」就像是由原本的字串:「A」再加上字串:「B」後產生的結果。

但實際上在記憶體中並不是這樣運作的,由於「Java」的字串具有「不可改變」的特性,因此,上述程式片段的執行方式是先產生字串:「A」,然後再產生字串:「B」,經運算後,再產生字串:「AB」,並將「str」指向了「AB」。

換句話說,在上述代碼片段的運算過程中,有三個「字串」被產生,但僅有「AB」被指向,而另外兩字串理論上會被「GC」機制所回收。

所以Java 為了降低「當字串重覆使用」時所消耗的資源成本,「JVM」實作了「字串池」的機制,其會在「Heap」中設置一塊「字串池」的區域,其專門用於存放「字串」,而在字串池裏的這些字串是允許被「重覆取用的」,如下圖

https://ithelp.ithome.com.tw/upload/images/20230920/20163139PxI4krK9xk.png

// Literal String
String s1 = "ABC";
String s2 = "ABC";
System.out.println(s1 == s2); // true

但要注意的是,並不是所有被產生的字串都一定會進入「字串池」,實際上只有以「Literal」形式,也就是藉由「雙引號」所產生的字串會被放在「字串池」中

https://ithelp.ithome.com.tw/upload/images/20230920/20163139eeqeQJhtss.png

// New String
String s1 = "ABC";
String s3 = new String("ABC");
System.out.println(s1 == s3); // false

字串如果用「new」的方式就不會所儲存的位置就不會在字串池中

所以不建議產生字串的時候用「new」,而是以「Literal」的形式。

https://ithelp.ithome.com.tw/upload/images/20230920/20163139I1wPZn28mJ.png

相等 Equals

上面都是用 == 來比較變數1 與 變數2 的『值』有沒有相等,字串是參考資料型態,變數1及變數1只是存放在Stack區的變數,他們的內容值是真實物件的reference,並不是物件內容

需要比對字串內容值的話,需要的是字串方法: equals()

String a = new String("hello");
String b = new String("hello");
System.out.println(a.equals(b));//true

再幫大家整理一下:

==

基本類型:比較內容值

物件資料類型:物件位址值

equals()

一般物件資料類型:物件位址值

String :比較內容值

今天先到這邊囉~明天再來說明基本型態的包裝類別!


上一篇
Day4-資料類型I
下一篇
Day 6 包裝類別
系列文
玩轉Java:從基礎打造你的程式超能力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言