java方法參數引用

結論:
     個人認爲,方法中傳遞的是引用;
      只是方法中如果對對象(變量)作出了改變,改變的是引用(指向了另一個地址)或者是自身的實例數據

package Test01;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Test {

	public static void main(String[] args) {
		HashMap<String,Object> hashMap = new HashMap<String, Object>();
		User user = new User();
		user.setAge("18");
		user.setName("hhh");
		hashMap.put("userKey", user);
		user.setAge("20");
		int i =100;
		hashMap.put("i", i);
		i=200;
		System.out.println("原始map:"+hashMap);
}

輸出:
     原始map:{userKey=User{age=‘20’, name=‘hhh’}, i=100}
過程:
     1). HashMap和User類加載實例化後,在Java堆中存儲了實例數據,在棧(實際是main棧幀的局部變量表,可參考Java內存區域)中存儲對應的對象引用hashMap、user。
     2).執行hashMap.put(“userKey”, user);hashMap對象實際存儲的是對象引用user,該引用與棧中的引用都指向同一塊java堆的內存地址(同一個user對象)
     3).執行user.setAge(“20”);修改了user的實例數據,由於同一個引用,所以hashMap裏user的數據也會改變。
     4).100和200作爲int字面量,在Test類加載後,已經存儲在方法區的運行時常量池,當執行int i =100;實際是將存儲在棧中的i指向常量池的100,
     5). 執行hashMap.put(“i”, i);存儲在hashMap實例對象裏的i和棧中的i一樣,都是指向常量池中的100
     6). 執行 i=200;只是將棧中的i重新指向了200,而hashMap裏的i還是指向常量池的100;如圖:
在這裏插入圖片描述
不想寫了,直接看例子吧
例子1:

public class tttMethod {
	public int tInt(int i) {
		i=2;
		return i;
	}
}
package Test01;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class GGGG {
    public static void main(String[] args) {
        int i =100;
        tttMethod tttMethod = new tttMethod();
        //testInt
        tttMethod.tInt(i);
        System.out.println("---方法不接受返回值i:"+i);
        i = tttMethod.tInt(i);
        System.out.println("---方法接受返回值i:"+i);
    }
}

輸出:
     —方法不接受返回值i:100
     —方法接受返回值i:2
     過程:
                執行tttMethod.tInt(i);時,在tInt的棧幀中,i指向常量池的100;
                當在方法中改變i=2,是tInt的棧幀的i改變了指向。
                當方法執行結束,tInt棧幀出棧。而main棧幀中的i依舊指向的是100;
                當i = tttMethod.tInt(i);時,main棧幀中的i就改變了指向,指向了常量池的2.

例子2:

public class tttMethod {
	public HashMap<String,Object> tReturnMethod(HashMap<String, Object> hashMap1) {
		hashMap1.put("oooo", "tReturnMethod");
		return hashMap1;
	}
	public void newMethod(HashMap<String, Object> hashMap2) {
		hashMap2=new HashMap<String, Object>();
		hashMap2.put("oooo", "newMethod");
	}
	public HashMap<String,Object> newReturnMethod(HashMap<String, Object> hashMap3) {
		hashMap3=new HashMap<String, Object>();
		hashMap3.put("oooo", "newReturnMethod");
		return hashMap3;
	}
}
package Test01;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class GGGG {

    public static void main(String[] args) {
        HashMap<String,Object> hashMap = new HashMap<String, Object>();
        hashMap.put("A","aaa");
        tttMethod tttMethod = new tttMethod();
//		tttMethod.tReturnMethod(hashMap);
        hashMap = tttMethod.tReturnMethod(hashMap);
        System.out.println("---不新建有返回hashMap修改:"+hashMap);      //{A=aaa, oooo=tReturnMethod}
//        hashMap = tttMethod.tReturnMethod(hashMap);
//        System.out.println("---不新建有返回hashMap修改:"+hashMap);      //{A=aaa, oooo=tReturnMethod}
//        tttMethod.newMethod(hashMap);
//		System.out.println("---新建無返回hashMap後修改:"+hashMap);      //{A=aaa}
//		hashMap = tttMethod.newReturnMethod(hashMap);
//		System.out.println("---新建有返回hashMap後修改:"+hashMap);      //{oooo=newReturnMethod}
    }
}

輸出如代碼後面註釋所示。
     過程:
               main棧幀中hashMap指向堆中的HashMap實例數據
               調用 tttMethod.tReturnMethod(hashMap);在tReturnMethod棧幀中hashMap1指向同一個堆中的
         HashMap實例數據;
               方法中hashMap1.put(“oooo”, “tReturnMethod”);改變了HashMap實例數據,所以main棧幀中的
         HashMap實例數據也改變了,所以輸出{A=aaa, oooo=tReturnMethod}
在這裏插入圖片描述
  當執行tttMethod.newMethod(hashMap);在newMethod棧幀hashMap2原本指向同一個HashMap實例數據
  當在方法中hashMap2=new HashMap<String, Object>();在堆內存新開闢塊內存,hashMap2指向新開闢的內存
  main棧幀中hashMap一直指向原來的HashMap實例數據,所以輸出{A=aaa}
在這裏插入圖片描述
  同理,hashMap = tttMethod.newReturnMethod(hashMap);也一樣,只是最後main棧幀中hashMap指向了新new的內存
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章