我已将变量map
分配给null
:
public static void main(String[] args){
Map map = null;
createMap(map);
System.out.println("map is:" + map);
}
我将变量map
传递给方法createMap
并重新分配:
public static void createMap(Map map){
if(map == null){
map = new HashMap();
map.put("key", "value");
}
}
变量地图仍为“空”,有人可以告诉我原因吗?
答案 0 :(得分:3)
为此,您需要了解按值传递和按引用传递的概念。
按值传递使用pass-by-value时,编译器将传递参数的值复制到调用函数,以复制到被调用函数的相应非指针或非引用参数。被调用函数中的参数使用传递的参数的值初始化。只要参数未被声明为常量,就可以更改参数的值,但更改仅在被调用函数的范围内执行;它们对调用函数中参数的值没有影响。
简单来说如果有int i = 5;
并且传递给函数void manipulate(int i)
,则将值5
复制到新位置并传递指针(地址)调用函数,现在如果对它进行任何更改,它们将不会被反映出来。
在你的情况下,你有一个Map
类型的对象,当你传递它时,会创建一个新的指针,指向一个null
的对象,并传递该地址,当你指定对于新对象,当您分配新指针时,不会反映更改,这与传递的地图对象所指向的不同。
如果您想要反映更改,请使用通过引用传递,但 Java 始终为按值传递,您可以使用 AtomicReference
public static void createMap(AtomicReference<Map> atomicmap)
{
Map map = atomicmap.get();
if(map == null)
{
map = new HashMap();
map.put("key", "value");
}
atomicmap.set(map);
}
public static void main(String[] args)
{
Map map = null;
AtomicReference<Map> atomicmap = new AtomicReference<Map>();
atomicmap.set(map);
createMap(atomicmap);
map = atomicmap.get();
System.out.println("map is:" + map);
}
答案 1 :(得分:2)
public static void createMap(Map map){
在上面的代码中,map
引用变量指向调用者方法传递的同一对象。
但是当你这样做时:
map = new HashMap();
创建一个新对象,map现在指向它。但是调用方法中的引用将继续指向传递的对象。因此,如果在创建新对象后对map
进行任何更改,则不会反映在调用者引用变量中。
这是:
Map map = null; // Caller reference variable
createMap(map);
此处map
仍然指向旧对象(不幸的是,在您的情况下为NULL)
答案 2 :(得分:0)
您只是在方法l
中操纵局部变量createMap
。第一个方法中的变量map
仍然指向null。
要了解其工作原理,请考虑以下事项:
在main
方法中,您正在创建变量map
,并将其指定为null。你现在在堆栈上有这个变量,但堆上仍然没有相应的对象。
然后将此变量作为参数传递给createMap
。 Java执行此调用by value
,即它创建变量的副本并将其与方法调用一起推送到堆栈。现在堆栈上有两个变量,堆上仍然没有对象。
最后,在createMap
方法中,创建一个新的Map对象并将其分配给l
,即第一个变量的副本。现在,堆栈上有两个变量,堆上有一个对象,其中一个指向Map对象:
地图---&gt;空值 l ---&gt;图
当createMap
方法返回时,弹出堆栈并释放变量l
。 map仍未指向Map对象 - 它从未执行过,它仍将指向null 。此外,由于Map对象现在没有实时引用,它将被下一个垃圾收集周期扫描。
所以,你最终得到的是堆栈中的一个变量,仍然指向null。
答案 3 :(得分:0)
是。因为引用在本地堆栈外部不可见(传入空引用的值)。你可以很容易地做到这一点 -
public static Map createMap(Map map){
if(map == null){
map = new HashMap();
}
map.put("key", "value"); // Really?
// More stuff.
return map;
}
然后改变你的调用方法
Map map = createMap(null); // This would then work
答案 4 :(得分:0)
您将null
传递给createMap
。 Java按值传递所有参数,而不是按引用传递。您的createMap
方法会为本地变量HashMap
分配一个新的map
,而不是您尝试传递的实例。 Here是一篇关于参数传递的文章。
答案 5 :(得分:0)
Java按值传递引用。
因此您无法更改传入的引用。 所以你要传递
createMap(map);
因此map将始终指向null。