Java的變量分為兩大類:基本數據類型和引用數據類型。
其中基本類型變量有四類8種:byte short int long float double char boolean,除了8種基本數據類型變量,其他變量都是引用數據類型,如類、接口、數組等。
基本數據類型,只有一塊存儲空間, 在棧中,存放的是具體數據值。
引用數據類型,有兩塊存儲空間一個在棧(Stack)中,一個在堆(heap)中。堆中存放對象實體(使用new關鍵字,即表示在堆中開辟一塊新的存儲空間),棧中存放對象在堆中所在位置的首地址。引用類型變量類似於C/C++中的指針。
引用:一個引用類型變量(棧中的一塊內存空間)保存了一個該類型對象在堆中所在位置的首地址,也稱作一個引用類型變量指向了一個該類型的對象,通過這個變量就可以操作對象中的數據。
看下面一段代碼:
class Person {
String name;
int age;
}
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "張偉";
p1.age = 17;
System.out.println("姓名:" + p1.name + ",年齡:" + p1.age);
Person p2 = new Person();
p2.name = "李麗";
p2.age = 12;
System.out.println("姓名:" + p2.name + ",年齡:" + p2.age);
p1 = p2;
p1.age = 13;
System.out.println("姓名:" + p1.name + ",年齡:" + p1.age); //姓名:李麗,年齡:13
System.out.println("姓名:" + p2.name + ",年齡:" + p2.age); //姓名:李麗,年齡:13
}
}
Person類對象的內存圖:
多個對象在堆內存中,都有不同的內存划分
當多個對象的引用指向堆同一塊內存空間(p1 = p2; 即將一個對象的引用賦值給另一個變量,兩個變量所記錄的地址值是一樣的,此時p1指向 p2所指向的對象,不再指向 p1原本指向的對象,如上圖所示),只要通過任何一個對象引用修改了對象中的數據,隨后,無論使用哪一個對象引用獲取數據,得到的都是修改后的值,因此,最后兩行打印語句的結果是一樣的。
所以,對於引用數據類型,如 Person p = new Person(); 將 p 簡單理解為對象名是不合適的。