1. 程式人生 > >JAVA值類型和引用類型的區別

JAVA值類型和引用類型的區別

回收 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值類型和引用類型的區別