理解java的JVM內存分佈的時候,學習了一下這個引用傳遞的知識點,並且仿照着例子寫了幾個demo方便理解。除開我們的四類八種數據類型(布爾型: boolean
字符型: char
整 形: byte short int long
浮點型: float double ),其他的都是引用類型。
1、我們先來理解一下引用以及它們的內存分佈:(對象存放在堆空間,引用存放在棧空間)
Object o1 = new Object();
從又往左看,首先創建一個Object對象,比如爲它分配的地址是40B1,存放在堆空間中;然後創建這個對象引用01,爲它分配的地址是2016,存放在棧空間中;這個o1就是對象的引用
總結:引用是變量,變量的值是所指向對象的起始地址;地址的值是無符號整形;引用本身也有地址;
2、引用傳遞舉例
Demo1:在使用基本數據類型進行引用傳遞時,由於可以修改,並且引用指向尚未更改,所以最後值可以修改
public class Demo1{
//主類
public static void main(String []args){
Test test1 = new Test();//test.temp=10
test1.temp = 20 ;
System.out.println(test1.temp);//test.temp=20
tell(test1);
System.out.println(test1.temp);//test.temp=30
}
//靜態方法tell()
public static void tell(Test test2){
test2.temp = 30 ;
}
}
class Test{
int temp = 10 ;
}
輸出:
20
30
Demo2:String引用傳值,由於String不可修改,重新賦值會在堆內存重新分配一塊內存,而原來的指向如果不被使用則會被java垃圾處理不定期回收。
public class Demo2{
//主類
public static void main(String []args){
String s1 = "aaa";
System.out.println(s1);//aaa
tell(s1);
System.out.println(s1);//aaa
}
//靜態方法tell()
public static void tell(String s2){
s2 = "bbb" ;
}
}
內存分析圖:這裏tell方法方法執行完畢,而且指向S1指向還是aaa,所以實際沒有被改變,而s2在方法執行過後會被java垃圾回收機制不定期回收。
輸出:
aaa
aaa
Demo3:這裏和上邊的區別就是我們的 new Test() 是的一個Test的一個實例,str1指向了它,在tell裏面形參str2也指向了它。temp是new Test() 裏面的一個屬性,也是一個引用放在棧空間,通過temp去操作AAA以及BBB,所以在調用tell方法的時候,str2.temp調用new Test() 的temp屬性,它在堆空間新分配了一塊空間存放BBB,temp指向了BBB,原來的AAA這塊內存因爲沒有使用而被垃圾回收機制回收。
public class Demo3{
//主類
public static void main(String []args){
Test str1 = new Test();
System.out.println(str1.temp);//AAA
tell(str1);
System.out.println(str1.temp);//aaa
}
//靜態方法tell()
public static void tell(Test str2){
str2.temp = "BBB" ;
}
}
class Test{
String temp = new String("AAA");
}
輸出:
AAA
BBB