我有以下代码
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 。请帮助。
答案 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)