为什么“null”对象不能通过方法分配

时间:2013-12-12 07:23:01

标签: java

  1. 我已将变量map分配给null

    public static void main(String[] args){
        Map map = null;
        createMap(map);
        System.out.println("map is:" + map);
    }
    
  2. 我将变量map传递给方法createMap并重新分配:

    public static void createMap(Map map){
        if(map == null){
            map = new HashMap();
            map.put("key", "value");
        }
    }
    
  3. 变量地图仍为“空”,有人可以告诉我原因吗?

6 个答案:

答案 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。