a和ia这两个引用指向的是同一个地址,ia=null,就把ia与这个地址断开,但地址内容并没有改变。ia.append("ok")修改ia指向的这个地址的内容,因为a和ia是指向同一地址,所以a的值也变了。

解决方案 »

  1.   

    to:ggzzkk..
     不好意思啊。我对您那句"ia=null,就把ia与这个地址断开,但地址内容并没有改变。"不太理解。。您能再解释一下吗?
      

  2.   

    a和ia都是指向new StringBuffer("ok")对象地址,ia=null,就是让ia不指向这个地址,ia为空。 
      

  3.   

    Remus:
    朋友你是不是chinajavaworld里的
    ggzzkk:
    "a和ia都是指向new StringBuffer("ok")对象地址"
    照你说不是和c++里reference作参数一样的吗。
    那好我这里还有个例子(已在jb7中运行通过):
    class Swap
    {
     public static void main(String args[])
     {
      Integer a, b;
      int i,j;
      a = new Integer(10);
      b = new Integer(50);
      i = 5;
      j = 9;
      System.out.println("Before Swap, a is " + a);
      System.out.println("Before Swap, b is " + b);
      swap(a, b);
      System.out.println("After Swap a is " + a);
      System.out.println("After Swap b is " + b);
      System.out.println("Before Swap i is " + i);
      System.out.println("Before Swap j is " + j);
      swap(i,j);
      System.out.println("After Swap i is " + i);
      System.out.println("After Swap j is " + j);
     }
     public static void swap(Integer ia, Integer ib)
     {
      Integer temp = ia;
      ia = ib;
      ib = temp;
     }
     public static void swap(int li, int lj)
    {
     int temp = li;
     li = lj;
     lj = temp;
     }
    }
    输出为:
    Before Swap, a is 10Before Swap, b is 50After Swap a is 10After Swap b is 50Before Swap i is 5Before Swap j is 9After Swap i is 5After Swap j is 9
    你作何解释?
      

  4.   

    to:sarsor;
    偶也常在那里转转。。:)
    我刚才思考了半天了,按自己的想法总结了一下:
    基本类型就不说了,都能明白,传递对像的时候是传引用,这不错,像:
    Object o1;
    Object o2=o1;
    这样,o1,o2是传引用,指的是同一个内存地址;但是在做为参数传给方法的时候,是传递的对像的引用的值!(to:ggzzkk 大哥,不知道这样理解对不?:)),在方法内部改变这个值并不会影响做为方法的参数(对像引用)的实际指向。
    所以,你给的例子中,swap(Integer ia,integer ib)的时候,实际上是swap ia,ib的值,并不是swap ia,ib所指向的地址!因此这个swap方法不会起作用!你明白了吗?(to:ggzzkk..你也明白了吗?)
      

  5.   

    你可以看下这个例子,看图应该就能明白。。;)
    http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
      

  6.   

    应该把java的句柄理解为C++ 的指针,而"不"是"引用"这样问题就理解了
      

  7.   

    to: prosong.偶从没看过c++。所以它的指针也就不知道是啥东西了。。;)
      

  8.   

    我靠,还存在这样的人。学习java连java的数据类型,以及参数引用机制这些基本的东东都不去理解的说,我服了你了。简单的说,java数据类型可以分成两类:基本类型和引用类型。(实际上是三类的,还是一类是叫做null类型的,看清楚不是null值,是null类型。)基本类型参数都是传值调用的,就是说函数自己拷贝了一份自己用,以后函数只使用自己拷贝的那个跟外面的没有关系的。引用类型参数说到底也是传值调用的(如果你熟悉指针引用的话就好理解多了)。不过不向基本类型,这里引用所谓传值的“值”是这个引用指向对象的地址值,而不是基本类型那样传的是,真正地址指向的真正数值的。所以引用参数调用说成是传址的。
      

  9.   

    to:zosatapo:
    引用类型参数说到底也是传值调用的(如果你熟悉指针引用的话就好理解多了)。不过不向基本类型,这里引用所谓传值的“值”是这个引用指向对象的地址值,而不是基本类型那样传的是,真正地址指向的真正数值的晕中高手哥。。能不能写个例子或是画个图表示一下。。偶等愚钝从字面上理解不透:)
      

  10.   

    大家的说法都基本正确,但也有很多错的地方(zosatapo的都是正确的)
    清大家把我的例子和Remus的例子结合起来看(其实这两个example form
    the same article)。
    就会发现问题:
    我的例子(在c++里是典型的reference传递,注意,reference传递和指针传递是有区别的,a,b 两个的值会对调)a,b 两个的值没对调,说明它是值传递(reference的值)。
    Remus的例子ia的值改变了,说明它与前者有区别,可以说是“c++里是典型的reference传递”(至少从表面看是这样),至于其实质区别偶don't know.
    矛盾由此产生……
    附:两个例子都是正确的我已经在jb7里试过了
      

  11.   

    附(相信对你们都大有帮助)原文如下:在不同的java新闻组中,参数是传值还是传址一直是一个经常被争辩的话题。误解的中心是以下两个事实:
    1、对象是传引用的
    2、参数是传值的
    这两个能够同时成立吗?一个字:是!在java中,你从来没有传递对象,你传递的仅仅是对象的引用!
    一句话,java是传引用的。然而,当你传递一个参数,那么只有一种参数传递机制:传值!
    通常,当程序员讨论传值和传引用时,他们是指语言的参数传递机制,c++同时支持这两种机制,
    因此,以前使用过c++的程序员开始好像不能确定的java是如何传参数的。java语言为了事情变得简单只支持参数传值的机制。
    java中的变量有两种类型:引用类型和原始类型。当他们被作为参数传递给方法时,他们都是传值的。
    这是一个非常重要的差别,下面的代码范例将说明这一点。在继续前,我们有必要定义一下传值和传引用。
    传值意味着当参数被传递给一个方法或者函数时,方法或者函数接收到的是原始值的副本。
    因此,如果方法或者函数修改了参数,受影响的只是副本,原始值保持不变。
    关于java中的参数传递的混乱是因为很多java程序员是从c++转变过来的。c++有引用和非引用类型的变量,
    并且分别是通过传引用和传值得。java语言有原始类型和对象引用,那么,按照逻辑,java对于原始类型使用传值而对引用是传引用的,
    就像c++一样。毕竟,你会想到如果你正在传递一个引用,那么它一定是传引用的。这是一个很诱惑人的想法,但是是错误的!
    在c++和java中,当函数的参数不是引用时,你传递的是值得副本(传值)。但是对于引用类型就不同了。在c++中,当参数是引用类型,
    你传递的是引用或者内存地址(传引用),而在java中,传递一个引用类型的参数的结果只是传递引用的副本(传值)而非引用自身。
    这是一个非常重要的区别!java不考虑参数的类型,一律传递参数的副本。仍然不信?如果java中是传引用,那么下面的范例中的swap
    方法将交换他们的参数。因为是传值,因此这个方法不是像期望的那样正常工作。
    class Swap
    {
     public static void main(String args[]) 
     { 
      Integer a, b; 
      int i,j;
      a = new Integer(10);
      b = new Integer(50); 
      i = 5;
      j = 9; 
      System.out.println("Before Swap, a is " + a); 
      System.out.println("Before Swap, b is " + b); 
      swap(a, b); 
      System.out.println("After Swap a is " + a); 
      System.out.println("After Swap b is " + b); 
      System.out.println("Before Swap i is " + i); 
      System.out.println("Before Swap j is " + j); 
      swap(i,j); 
      System.out.println("After Swap i is " + i);
      System.out.println("After Swap j is " + j); 
     }
     public static void swap(Integer ia, Integer ib)
     {
      Integer temp = ia; 
      ia = ib; 
      ib = temp; 
     }
     public static void swap(int li, int lj) 

     int temp = li; 
     li = lj; 
     lj = temp; 
     } 
    } 上面程序的输出是: Before Swap, a is 10 
    Before Swap, b is 50
    After Swap a is 10 
    After Swap b is 50 
    Before Swap i is 5 
    Before Swap j is 9 
    After Swap i is 5 
    After Swap j is 9 因为swap方法接收到的是引用参数的副本(传值),对他们的修改不会反射到调用代码。译者注:在传递引用和原始类型时还是有不同的,考虑以下的代码: 
    class Change
    {
     public static void main(String args[]) 
     { 
      StringBuffer a=new StringBuffer("ok"); 
      int i;
      i = 5;
      System.out.println("Before change, a is " + a); 
      change(a); 
      System.out.println("After change a is " + a); 
      System.out.println("Before change i is " + i); 
      change(i); 
      System.out.println("After change i is " + i);
     }
     public static void change(StringBuffer ia)
     {
      ia.append(" ok?");
     }
     public static void change(int li) 

     li = 10; 
     } 
    }程序的输出为:Before change, a is ok
    After change a is ok ok?
    Before change i is 5
    After change i is 5即如果传递的是引用,那么可以修改引用对象的内容,这个改变会影响到原来的对象,而传递的如果是原始类型则不会有影响。
    这个也是造成误解的原因之一吧。
      

  12.   

    Point q = new Point(3.0, 4.5);  // A point with an X coordinate of 3
    changeReference(q);  // Prints 3,2,1 and modifies the Point
    System.out.println(q.x);  // The X coordinate of q is now 0!
    When the changeReference() method is invoked, it is passed a copy of the reference held in variable q. Now both the variable q and the method parameter p hold references to the same object. The method can use its reference to change the contents of the object. Note, however, that it cannot change the contents of the variable q. In other words, the method can change the Point object beyond recognition, but it cannot change the fact that the variable q refers to that object.