JAVA值類型和引用類型的區別
阿新 • • 發佈:2018-08-04
回收 attribute 布爾類型 tor main ava 引用 接口類 test
java這兩種數據類型分別有哪些?
java 中的數據類型分為兩大類:值類型(基本數據類型)和引用類型(復合數據類型)
一:值類型:
整數類型(byte,short,int,long) 浮點類型(float,double) 布爾類型(boolean) 字符類型(char)
二:引用值類型:
除了值類型外就是引用值類型了,引用值類型有 類類型(class) 數組 接口類型(interface)
值類型和引用類型的區別
值傳遞和引用傳遞
基本數據類型的賦值是值傳遞,當值類型變量a賦值給值類型變量b之後,再去改變a的值那麽b不會隨著a的改變而改變。
int a=1;
int b=a;
a=2;
System.out.println("a:"+a+"b:"+b);
引用值類型的賦值是引用傳遞,傳遞的是對象的引用地址。當引用值類型變量a賦值給引用值類型變量b之後,再去改變a的值那麽b會隨著a的改變而改變。
public class Test(){
int num;
public Test(int num){
this.num=num;
}
public void steNum(int num){
this.num=num;
}
public static void main(String args[]){
Test ta= new Test(1);
Test tb= new Test();
tb=ta;
ta.setNum(2);
System.out.println("ta:"+ta.num+"tb:"+tb.num);
}
}
2 內存分配
之所以會出現以上的現象是因為,值類型數據和引用類型數據在在Java中的內存分配不一樣。
值類型數據是直接存儲在棧中,Java JVM直接在棧中給數據開辟了一塊空間,直接存儲數據的值。
int a=1; //JVM為變量a在棧中開辟了一塊空間(假設為A),棧中存儲的是 1;
int b=a; //JVM為變量b在棧中開辟另了一塊空間(假設為B),棧中存儲的也是 1;
a=2; //為變量a重新賦值,棧空間A中存儲的值改為2,棧空間B中存儲的值不變為1
引用類型數據並不是直接存儲在棧中,Java JVM會在堆中給數據分配內存空間,堆存儲數據。棧存儲的是指向對應堆的地址。可以說是棧中的地址引用了堆中的數據。
Test ta= new Test(1);
/* JVM為ta變量在堆中開辟一塊空間(假設為K),那麽堆空間K存儲的是 1;
JVM為ta變量在棧中開辟一塊空間(假設為A),那麽棧空間A存儲的是指向堆空間的地址(假設為1000)
*/
Test tb= new Test(0);
/* JVM為tb變量在堆中開辟一塊空間(假設為J),那麽堆空間J存儲的是 0;
JVM為ta變量在棧中開辟一塊空間(假設為B),那麽棧空間B存儲的是指向堆空間的地址(假設為2000)*/
tb=ta;
/*棧空間B中存儲的地址從2000改為1000(從指向J改為指向K) 現在ta 和 tb 都引用堆空間K*/
ta.setNum(2);
/*堆空間K中存儲的值改為2 所以ta.num和tb.num 都是2 */
垃圾回收機制
當堆空間存儲的對象沒有被棧空間中存儲的地址所指向時(引用時),該對象會被自動清理掉。如前面提到的堆空間J中本來存儲著 0
Test tb= new Test(0);
但是
tb=ta;
不再有地址指向堆空間J中本來存儲的0,0會被自動清楚。
JAVA值類型和引用類型的區別