关于Java方法传参时的问题

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++,可能这个问题更容易理解。