Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java传递值示例帮助我理解_Java - Fatal编程技术网

java传递值示例帮助我理解

java传递值示例帮助我理解,java,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.p

我有以下代码

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,Sangkar”] }。<代码> M <代码>是指向ARARYLIST对象的指针,它包含内存地址值(对于前考虑0xF34)。。当我们将m传递给update方法时,局部变量l将被设置为指向内存中arraylist对象的0xf34。当我们将此变量l设置为null时,内存地址将arraylist替换为null,因此变量m也应引用null。我说得对吗。请帮助。

update
方法仅设置局部
l引用
null
,而不更改有关传入对象的任何内容。

否,编译器拥有它的权利。:)


参数
l
包含对分配给
m
l
的ArrayList对象的引用,该对象被更新为null,并且以后在
更新()中使用
l
method会将其视为null。但是
l
是一个单独的变量,其作用域仅在该方法内——它没有以任何方式链接到
m
(除了它们最初包含对同一对象的引用这一事实)理解这一点的关键是要记住,所有对象都是通过引用间接访问的。当对象作为参数传递给方法时,实际传递的“值”是引用,而不是对象本身

当您在
update
方法中取消
l
参数时,您将特定引用设置为
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
设置为空时,这是一个仅影响
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
引用的对象,而不仅仅是引用本身


请注意,这不会引发NullPointerException,即使l被赋值为null。与以前一样,它是一个引用,因此它是对该引用值的本地赋值。

不,你说得不对。Java和其他许多高级语言一样,都采用了


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

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


如果您将m设置为表示X,将l设置为表示X。我们有两个变量表示相同的地址,如果您将其中一个变量更改为null,则另一个变量将保留为旧值。

对于那些感兴趣的人来说,还有一些额外的读数


假设,
新建ArrayList()
返回存储新ArrayList对象的地址2000

List m=new ArrayList()
: 比如说,m@9999=2000,这里让“@”后面的数字表示存储“m”的地址,“=”后面的数字表示“m”的值(这也是一个地址,因为它是引用类型)。因此,地址9999的“m”现在保存着2000,这是新创建的ArrayList对象的地址

更新(m)
: 由于Java总是按值调用,它调用update()方法复制存储在m中的值,m是2000。因此,update()定义中的参数“l”保存值2000(这也是先前创建的ArrayList对象的地址)。因此我们可以说, l@8888=2000(地址8888处的l的值为2000)

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

System.out.println(m)

现在m的值是多少?它仍然是2000。更新()方法没有更改m的值。该方法只是更改了其局部变量“l”的值。因此“m”仍然引用以前创建的ArrayList对象,并且正在打印中。

更准确的说法是,引用是按值传递的。Java在任何地方都没有按引用传递语义。稍后,当您说“t”时,您会得到它hat“指针m是按值复制的”(尽管我认为它是引用而不是指针;它不一定是原始地址)-我认为删除第一段肯定会改善这个答案…你是对的,这不是我的意图-我已经更改了第一段以更接近地反映我的意图。感谢skeet和mdma。知道编译器如何处理局部范围吗?谢谢大家宝贵的解释。