java传递值示例帮我理解

时间:2010-08-17 15:18:14

标签: java

我有以下代码

class sample
{

  public void update(List l)
  {
      l = null;
  }

  public static void main (String[] args)
  {

      List m = new ArrayList();
      m.add("suresh");
      m.add("sankar");
      new sample().update(m);
      System.out.println(m);
  }
}

答案是{[“suresh,”sankar“]}。m是一个指向arraylist对象的指针,它包含一个内存地址值(例如0xf34)。当我们传递m到更新方法,局部变量l将设置为0xf34,指向内存中的arraylist对象。当我们将null设置为此变量l时,内存地址将null替换为arraylist,因此变量m也应该引用null.am i right 。请帮助。

7 个答案:

答案 0 :(得分:3)

不,编译器没错。 :)

参数l包含对分配给m的ArrayList对象的引用。 l更新为null,事实上l方法中任何后来使用update()都会将其视为null。但是l是一个单独的变量,只在该方法中具有范围 - 它没有以任何方式链接到m(除了它们最初包含对同一对象的引用的事实)。

答案 1 :(得分:2)

理解这一点的关键是要记住所有对象都是通过引用间接访问的。当一个对象作为参数传递给方法时,实际传递的“值”是一个引用,而不是对象本身。

当您在l方法中清空update参数时,您将设置对null的特定引用 - 原始引用m保持不变,并且对象两个参考文献中提到的也没有改变。

如果您了解C / C ++,那么可以将其解释为:

void update(List* l)
{
   l = NULL; // set the pointer to null - the object (*list) is unmodified
}

void main()
{
   List* m = ...;
   update(m);
   printf(m->values());
}

指针m按值复制。指向的对象(列表* m)不会以任何方式改变。指针的值从m复制到l。当l设置为NULL时,这是仅影响l指针值的本地更改。

以下是一个通过引用传递涉及非本地更改的示例

class NonLocalChange
{
   public void change(int[] i) {
      i[0] = 2;
      i = null;
   }

   public static void main(String[] s) {
      int[] m = new int[1];
      m[1] = 3;
      change(m);
      System.out.println(i[0]);
   }
}

打印的结果为2。这是因为change方法更改了l引用的对象,而不仅仅是引用本身。

请注意,即使l被指定为null,也不会抛出NullPointerException。和以前一样,它是一个引用,因此它是对该引用值的本地赋值。

答案 2 :(得分:1)

您的update方法只会将本地l引用设置为null,而不会更改传入对象的任何内容。

答案 3 :(得分:1)

想象一下你的堆中有一个地址(例如X)。

如果你设置m引用X以及l引用X.我们有两个引用相同地址的变量,如果你将其中一个改为null,另一个将保留为旧值。

答案 4 :(得分:1)

让我们说,new ArrayList()返回存储新ArrayList对象的地址2000。

List m = new ArrayList(): 比方说,m @ 9999 = 2000,这里让'@'后面的数字表示存储'm'的地址,'='后面的数字代表'm'的数字(这也是一个地址)因为它是参考类型)。所以现在地址9999处的'm'保存2000,这是新创建的ArrayList对象的地址。

update(m): 由于Java始终是按值调用,因此它调用update()方法复制存储在m中的值,即2000.所以现在update()定义中的参数'l'保存值2000(这也是地址先前创建的ArrayList对象)。所以我们可以说, l @ 8888 = 2000(地址8888处的'l'保持值2000)

l = null: 所以现在,l @ 8888 = null

System.out.println(m): 现在m的价值是多少?它仍然是2000. update()方法没有改变m的值。该方法刚刚更改了其局部变量'l'值。所以'm'仍然引用先前创建的ArrayList对象并正在打印。

答案 5 :(得分:0)

不,你不对。与许多其他高级语言一样,Java使用call by sharing

您可以这样想:对实际参数的引用是按值传递的。这意味着在被调用函数中,引用最初指向相同的值,因此对值本身的任何更改在被调用函数的范围之外都是可见的,但是对本地引用的任何更改都不是。就好像传递了地址的副本一样。

答案 6 :(得分:0)

对那些感兴趣的人有一些额外的阅读。

objects and primitives

java+pass+by+value search

相关问题