2010-08-17 45 views
2

我有以下代码的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); 
    } 
} 

答案将是{[“苏雷什,”桑卡尔“]}。该m是一个指针数组列表对象时,它包含一个内存地址值(对于前者考虑为0xf34),当我们传递m来更新方法时,局部变量l将被设置为0xf34,指向内存中的数组列表对象。当我们将null设置为这个变量l时,内存地址将替换因为变量m也应该指null.am我right.please帮助。

+0

谢谢大家的宝贵意见。 – 2010-08-17 16:03:38

回答

3

不,编译器正确。 :)

参数l包含对分配给m的ArrayList对象的引用。 l被更新为空,并且在update()方法内的任何后续使用l都会将其视为空。但是l是一个单独的变量,它只在该方法中具有作用域 - 它不以任何方式链接到m(除了它们最初包含对同一对象的引用)。

+0

感谢雅各的答案。 – 2010-08-17 15:33:46

1

你的update方法只是设置本地l参考null而不更改任何有关传入的对象。

2

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

当你空出的update方法l参数,你具体提及设置null - 原始参考m保持不变,由两个引用引用的对象也保持不变。

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由值复制:

如果知道C/C++,那么这可以被改写为。指向的对象(列表* 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

说这个引用是按值传递的,它* *更准确。 Java不**在任何地方都通过引用语义传递。当你说“指针m被值复制”(虽然我会说它是一个引用而不是一个指针;它不一定是一个原始地址)时,你会很清楚地知道 - 我认为这个答案会肯定会通过删除第一段来改进... – 2010-08-17 15:32:13

+0

你是对的,那不是我的意图 - 我已经改变了第一段,以更密切地反映我的意图。 – mdma 2010-08-17 15:43:16

+0

感谢飞碟和mdma。任何想法如何编译器处理本地作用域。 – 2010-08-17 15:51:29

0

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

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

1

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

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

1

比方说,new ArrayList()回报解决2000年在其新的ArrayList对象存储。可以说,m @ 9999 = 2000,这里让后面的数字'@'表示'm'存储的地址,'='后面的数字表示'm'的值(这也是一个地址,因为它是一个参考类型)。所以现在在地址9999处的'm'保存了2000,这是新创建的ArrayList对象的地址。因为Java始终是按值调用的,所以它调用update()方法复制存储在m中的值为2000.所以现在update()定义中的参数'l'保存值2000 (这也是以前创建的ArrayList对象的地址)。所以我们可以说, l在8888 = 2000( 'L' 的地址8888存放值2000)

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

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

+0

感谢您花费宝贵的时间来解释 – 2010-08-17 16:03:09