public class Test {
/**
* @param args
*/
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("1", "value");
changeMap(map);
System.out.println(map);
}
public static void changeMap (Map map){
map=null;
// map.clear();
}
}
以上程序的运行结果是什么?
如果将changeMap方法改为
public static void changeMap (Map map){
// map=null;
map.clear();
}
结果又是什么?
请各位解答,谢谢大侠!
为了能让你看得更明白,我把你的程序代码修改如下(注:只修改了你的方法形参名,,为了和你main方法中的那个map区分开):
[code="java"]public static void changeMap(Map map2) {
map2 = null;
//map2.clear();
}[/code]
首先你应该明白一点,[color=red]在Java中,任何对象都是在堆上分配空间的,而方法中的变量是在栈上分配空间的[/color]。
还要注意,[color=red]引用和对象的区别,引用就相当于指针。引用指向的是实实在在的对象[/color]。
只要明白以上两点,就好办了。
当程序执行完main方法中[color=red]HashMap map = new HashMap(); [/color]这条语句后,引用变量map指向了堆中的一个对象(为了容易理解,用字母A代表该对象)。用图表示就是:[b][color=red]map---->A[/color][/b]
[color=darkred]注意:这里的map是在栈上分配的,而A是在堆上分配的。[/color]
当程序执行到[color=red]changeMap(map); [/color]这里的时候,会将栈上的引用变量map(引用,就相当于指针),传递给该方法的形参map2,这个时候,[color=red]该方法进入方法栈中,同时在栈上为形参map2分配了空间,既然map赋值给了map2,那么现在情况是:map2也指向了堆上的对象A[/color]。此时,引用变量map和引用变量map2都指向了对象A。
用图表示就是:[color=red]map----->A <-------map2[/color]
然后程序就从main方法中,进入了public static void changeMap (Map map2)中。
紧接着就执行该方法中的第一条语句[color=red]map2 = null[/color];
这条语句执行后,引用变量map2被赋值为null,就是说,map2现在不指向任何对象了.
现在用图表示就是:[color=red]map----->A [/color] [color=blue]
而map2在该方法退出之后,也就自然消失了。但是map仍然指向对象A。[/color]
然后从该方法中退出,接着执行[b][color=red]System.out.println(map); [/color][/b]这条语句;
[color=red]这条语句中的变量时map,可map仍然指向的是对象A[/color],所以就把A的内容给打印出来了。
置于下边的这个方法
[code="java"]public static void changeMap(Map map2) {
//map = null;
map2.clear();
}[/code]
我不用说,你应该就明白了吧。
从main方法中调用这个方法,当进入这个方法后,引用变量map和map2共同指向了对象A,然后执行[b][color=red]map2.clear();[/color][/b],
[color=red]既然是共同指向一个对象,那么用任何一个引用来修改所指向的对象,效果是一样的,都会是对象的状态发生变化。当退出该方法后,这个方法栈也随之释放空间,当然map2也就不存在了,这个时候,你再输出map,那么就是修改后的内容,所以为空。[/color]
我说了这么多,应该明白了吧。
对象的话,就是传引用,
public static void changeMap (Map map){
map=null;
//这样只是把虚参数的引用设为null,而HashMap map = new HashMap();
//的map还是引用原来的对象
// map.clear();
}
map(main方法中的map) -> new HashMap();
当进行changeMap方法时
map(changeMap方法中的map) = map(main方法中的map);
执行到map=null;时
map(changeMap方法中的map) -> null;
而 map(main方法中的map) -> new HashMap();
如果将changeMap方法改为
public static void changeMap (Map map){
// map=null;
map.clear();
}
那就把map中的映射都清除了
结果就为{}
这个问题,还是用图片说,比较容易理解,说了那么多,也不知道你明白不。
记住一点就行了:[color=red]引用变量在栈上,对象在堆上[/color]。如果你学过C或C++,可能这个问题更容易理解。