结论:
个人认为,方法中传递的是引用;
只是方法中如果对对象(变量)作出了改变,改变的是引用(指向了另一个地址)或者是自身的实例数据
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的内存