8 參考資料型別和基本資料型別大不同
參考資料型別是Java程式語言的重心,因效率問題Java不使用new指令產生基本資料型別的物件,致使Java納入了非物件(non-object)元素。兩種資料型別的相異處如下:
(1)程式執行時的記憶體存放位置
基本資料型別存放於名為Stack的記憶體區塊,各基本型別因資料長度較小且固定,存放於效率較高的Stack區塊。
參考資料型別存放於名為Heap的記憶體區塊,需使用new指令產生的物件皆存放於此,此區塊記憶體處理效率較Stack區塊為差。
(2)變數資料內容
基本資料型別屬實值型別,變數存放的是實際的值,參考資料型別存放的是參考,也就是物件的位址。
(3)運算結果相異
因為參考資料型別變數存放的是位址,變數經過指定運算(=)後,人們對其後續的運算所期待的結果,和實際上的結果有所出入,也就是說和基本資料型別的運算結果是不同的。有關這一點必須理解清楚,下面將舉例說明之。
(註:Java真的有點難度,同屬參考資料型別的String又和其他物件型別不同,將另闢專章討論,此處僅對自建類別物件舉例。)
<基本型別的指定運算(賦值)例>基本資料型別
public class PriType{
public static void main(String[] args){
int i1 = 222;
int i2 = 333;
System.out.println("i1、i2初期值:");
System.out.println("i1 = " + i1);
System.out.println("i2 = " + i2);
i2 = i1;
System.out.println("i2 = i1指定運算後:");
System.out.println("i1 = " + i1);
System.out.println("i2 = " + i2);
i1 = 111;
System.out.println("i1=111更改內容後:");
System.out.println("i1 = " + i1);
System.out.println("i2 = " + i2);
}
}
執行結果:C:\js>java PriType
i1、i2初期值:
i1 = 222
i2 = 333
i2 = i1指定運算後:
i1 = 222
i2 = 222
i1=111更改內容後:
i1 = 111
i2 = 222
<資料遷移圖示>
Stack
i1=222 |
i2=333 |
↓ s2=s1
Stack
i1=222 |
i2=222 |
↓ s1=111
Stack
i1=111 |
i2=222 |
<參考型別的指定運算(賦址)例>自建類別物件
class StringA{
String mos = new String();
}
public class RefType{
public static void main(String[] args){
StringA s1 = new StringArray ();
StringA s2 = new StringArray ();
s1.mos = "男人比女人更容易招惹蚊子";
s2.mos = "物體愈黑,蚊子愈感興趣";
System.out.println("s1.mos、s2.mos初期值:");
System.out.println("s1.mos = " + s1.mos);
System.out.println("s2.mos = " + s2.mos);
s2 = s1;
System.out.println("s2 = s1指定運算後:");
System.out.println("s1.mos = " + s1.mos);
System.out.println("s2.mos = " + s2.mos);
s1.mos = "大人比小孩更容易被蚊子咬";
System.out.println("s1更改內容後:");
System.out.println("s1.mos = " + s1.mos);
System.out.println("s2.mos = " + s2.mos);
}
}
執行結果:C:\js>java RefType
s1.mos、s2.mos初期值:
s1.mos = 男人比女人更容易招惹蚊子
s2.mos = 物體愈黑,蚊子愈感興趣
s2 = s1指定運算後:
s1.mos = 男人比女人更容易招惹蚊子
s2.mos = 男人比女人更容易招惹蚊子
s1更改內容後:
s1.mos = 大人比小孩更容易被蚊子咬
s2.mos = 大人比小孩更容易被蚊子咬
<資料遷移圖示>
Stack |
|
Heap |
||
s1位址a1 |
→ |
a1 |
mos="男人比女人更容易招惹蚊子" |
|
s2位址a2 |
→ |
a2 |
mos="物體愈黑,蚊子愈感興趣" |
|
↓ s2=s1
Stack |
|
Heap |
||
s1位址a1 |
→ |
a1 |
mos="男人比女人更容易招惹蚊子" |
|
s2位址a1 |
↗ |
a2 |
mos="物體愈黑,蚊子愈感興趣" |
|
↓ s1.mos = "大人比小孩更容易被蚊子咬"
Stack |
|
Heap |
||
s1位址a1 |
→ |
a1 |
mos="大人比小孩更容易被蚊子咬" |
|
s2位址a1 |
↗ |
a2 |
mos="物體愈黑,蚊子愈感興趣" |
|
s2指定為s1運算(s2=s1)後,因參考型別變數內容為位址,故指向同一位址的物件,s1、s2的mos內容是同一個了,之後更改了s1的mos內容,也就等於改了s2的mos內容。
因沒任何物件指向虛線無色的a2位址記憶體區塊,會成為系統GC(garbage collector)記憶體清理回收的對象,回收後可供給其他物件使用。
留言列表