基本類型數據在內存中的存儲非常簡單,引用類型是把對象的地址放到棧內存中,數據放在堆內存中。在這通過幾個小程序簡單描述一下引用類型數據在內存中的存儲過程:
class Person{
String name;
int age;
void say(){
System.out.println("姓名:"+name+",年齡:"+age);
}
}
public class Demo01{
public static void main(String args[]){
Person p1=new Person();
Person p2=new Person();
p1.name="張三";
p1.age=20;
p2=p1;
p1.say();
p2.say();
p2.name="李四";
p2.age=40;
p1.say();
p2.say();
}
}
上面的程序先新建了一個Person類,里面有兩個成員變量還有一個成員方法。然后創建了一個Demo01類。執行如下代碼:
Person p1=new Person;
Person p2=new Person();
就會為兩個Person實例對象分配內存空間,將兩個對象初始化,內存分配如圖1所示:

執行
p1.name="張三";
p1.age=20;為實例對象p1賦值,內存分布如圖2所示:

執行
p2=p1;是將實例對象p2指向實例對象p1的內存空間,原來為實例對象p1分配的內存空間就會失去指向,這樣當系統執行垃圾(GC)技術時就會將這一部分內存釋放。內存分步如圖3所示:

執行
p1.say();
p2.say();
就會輸出:
姓名:張三,年齡:20
姓名:張三,年齡:20
執行
p2.name="李四";
p2.age=40;
就會將原先的值覆蓋,內存分配如圖4所示:

執行
p1.say();
p2.say();
就會輸出
姓名:李四,年齡:40
姓名:李四,年齡:40
這就是引用類型數據的存儲過程。java程序采用這種存儲方式主要有兩個原因:
1.棧內存存取速度非常快,僅次于寄存器。2.與垃圾回收機制(GC)相連,有利于機制刪除沒有指向的堆內存數據,釋放內存空間。
上面的程序執行
p2=p1;
這條語句后,將p2指向了p1所指向的數據并不能完成復制功能,我們可以稍作修改就可以完成復制功能,程序如下:
class Person{
String name;
int age;
void say(){
System.out.println("姓名:"+name+",年齡:"+age);
}
}
public class Demo02{
public static void main(String args[]){
Person p1=new Person();
Person p2=new Person();
p1.name="張三";
p1.age=20;
p2.name=p1.name;
p2.age=p1.age;
p1.say();
p2.say();
p2.name="李四";
p2.age=40;
p1.say();
p2.say();
}
}
這個程序的輸出結果是:
姓名:張三,年齡:20
姓名:張三,年齡:20
姓名:張三,年齡:20
姓名:李四,年齡:40
我們來分析它的內存存儲過程,執行代碼
Person p1=new Person();
Person p2=new Person();
p1.name="張三";
p1.age=20;
它的存儲過程如圖1和圖2相同,執行代碼
p2.name=p1.name;
p2.age=p1.age;
它并沒有將p2指向p1所指向的數據,而是將p1所指向的數據復制給p1所指向的數據。它的內存分配過程如圖5所示:

執行代碼
p1.say();
p2.say();
就會輸出
姓名:張三,年齡:20
姓名:張三,年齡:20
執行代碼
p2.name="李四";
p2.age=40;
修改了p2所指向的數據的值,但沒有修改p1所指向的數據的值。內存分配過程如圖6所示:

執行代碼
p1.say();
p2.say();
就會輸出
姓名:張三,年齡:20
姓名:李四,年齡:40
下面我們看下一個程序
class Person{
String name;
int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return name;
}
public int age(){
return age;
}
public void say(){
System.out.println("姓名:"+name+",年齡:"+age);
}
}
public class Demo03{
public static void main(String args[]){
Person[] per=new Person[2];
per[0]=new Person();
per[1]=new Person();
per[0].setName("張三");
per[0].setAge(20);
per[1].setName("李四");
per[1].setAge(40);
for(int i=0;i<per.length;i++){
per[i].say();
}
}
}
上面的程序輸出結果為
姓名:張三,年齡:20
姓名:李四,年齡:40
此程序首先建立一個Person類,里面有成員變量和成員方法,然后定義一個Demo03類,執行代碼
Person[] per=new Person[2];
per[0]=new Person();
per[1]=new Person();
建立一個Person對象的數組并初始化,這里的初始化只是將數組元素指向null,而并沒有在堆內存中分配空間,內存存儲如圖7所示:

執行代碼
per[0]=new Person();
per[1]=new Person();
這才是為數組元素開辟了堆內存空間并初始化,如圖8所示:

執行代碼
per[0].setName("張三");
per[0].setAge(20);
per[1].setName("李四");
per[1].setAge(40);
將張數據存儲到各個數組元素所指向的堆內存中,如圖9所示:
執行代碼
for(int i=0;i<per.length;i++){
per[i].say();
}
是將數組中的值輸出出來,就會輸出以上輸出結果。
java引用類型的存儲過程就是這樣。這只是在下的一個小見解,可能有不到位或不
正確的地方,歡迎各位朋友提出見解,共同分享知識。