java方法調用中的值傳遞和引用傳遞


一. 首先java中的基礎數據類型 byte,short,int,long,float,double,boolean,char

 1. 通過基本數據類型聲明的局部都是存儲java虛擬機棧當中

 2. 非基本數據類型,存儲於java 堆內存當中

 

二  基本類型 和 引用類型的不同之處

int num = 10;
String str = "hello";

1. 如圖所示,num是基本類型,值就直接保存在變量中。而str是引用類型,變量中保存的只是實際對象的地址。一般稱這種變量為"引用",引用指向實際對象,實際對象中保存着內容。

 

 三  賦值運算符(=)的作用

num = 20;
str = "java";
1. 對於基本類型 num ,賦值運算符會直接改變變量的值,原來的值被覆蓋掉。
2. 對於引用類型 str,賦值運算符會改變引用中所保存的地址,原來的地址被覆蓋掉。但是原來的對象不會被改變(重要)。
3. 如上圖所示,"hello" 字符串對象沒有被改變。(沒有被任何引用所指向的對象是垃圾,會被垃圾回收器回收)

 

四.  代碼與結果

public class ComboBox {
    public static void main(String[] args) throws Exception {
        int a = 100000;
        funA(a);// 傳遞的基本數據類型
        System.out.println("a = " + a);
        
        Integer b = new Integer(100000);
        funB(b);// 傳遞非基本數據類型(包裝類)
        System.out.println("b = " + b);
        
        Integer c = new Integer(100000);
        funC(c);// 同B 
        System.out.println("c = " + c);
    }
    
    public static void  funA(int a) {
        a = 9999999;
    }
    public static void  funB(Integer b) {
        b = 9999999;
    }
    private static void funC(Integer c) throws Exception {
        //JDK未提供Integer修改vlaue值的方式,通過反射修改
        Field field = Integer.class.getDeclaredField("value");
        field.setAccessible(true);
        field.set(c, 999999);
    }
}

a = 100000 b = 100000 c = 999999

 

FunA鏈路:

      

 

 

FunB鏈路:

 

 

FunC鏈路圖

 

 

 五. 總計與分析

    局部變量和方法參數在jvm中的儲存方法是相同的,都是在棧上開辟空間來儲存的,隨着進入方法開辟,退出方法回收。以32位JVM為例,boolean/byte/short/char/int/float以及引用都是分配4字節空間,long/double分配8字節空間。

    在JVM內存模型中有,stack和heap的存在,但是更准確的說,是每個線程都分配一個獨享的stack,所有線程共享一個heap。對於每個方法的局部變量來說,是絕對無法被其他方法,甚至其他線程的同一方法所訪問到的,更無法修改。

    當我們在方法中聲明一個 int i = 0,或者 Object obj = null 時,僅僅涉及stack,不影響到heap,當我們 new Object() 時,會在heap中開辟一段內存並初始化Object對象。當我們將這個對象賦予obj變量時,僅僅是stack中代表obj的那4個字節變更為這個對象的地址。

   上面中的傳遞?FunA傳遞了棧內存具體的值 num = 10000(FunA stack中存一份副本,形參), FunB傳遞了棧內num對象的地址 num = 0x000002(FunB stack中存一份副本,形參), FunC和FunB 一樣中傳遞了棧內num對象的地址 num = 0x000002(但是對目標對象堆內存中的值做了修改)

    如果是數據類型,會直接當棧中存儲的基本值傳遞給了形式參數復制一份。如果是非基本數據類型,是把實際參數的引用的地址復制了一份,傳遞給了形式參數,簡單說就是把實參對象引用的地址當做值傳遞給了形式參數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM