有两个例子,看了结果以后不大明白,请教一下各位大虾
public class Change {
public static void main(String args[]) 

  StringBuffer a=new StringBuffer("ok"); 

  System.out.println("Before change, a is " + a); 
  change(a); 
  System.out.println("After change a is " + a); 
         } public static void change(StringBuffer ia)
{
   ia.append(" ok?");
}
}
运行结果是:
Before change, a is ok
After change a is ok ok?第二个例子:
public class TestRefer {
public static void main(String args[]){ 
  Integer a;  
  a = new Integer(10);
  System.out.println("Before Change, a is " + a); 
  change(a);
  System.out.println("After Change a is "+a);
}

public static void change(Integer arg){
  arg = new Integer(40);
}
 
}
运行结果是:
Before Change, a is 10
After Change a is 10 为什么第一个例子中对象会改变,而第二个例子中却没有改变

解决方案 »

  1.   

    严格说,JAVA里传参都是也只有按值的,但当参数是对象名时,对象名实质上是指向内存中真实对象的一个引用,类似C++的指针,所以函数内对传进的对象操作时,其实是对原始对象操作了。对象名本身却是按值传的的,它被复制了一个副本传给了调用它的函数体。
      

  2.   

    首先,要清楚,在java中,参数对象的传递都是值的传递,这里的值,是参数对象的引用。这跟c或者c++是不一样的,c或者c++中参数对象的传递可以是值也可以是引用。
    理解了这点后,我们来看看你的例子,首先看看例一:在调用方法change时,把StringBuffer的对象a的引用作为值传递给change,运行ia.append(" ok?")后,改变了a地址的里面的内容,但是,a的引用是不变的,所以运行System.out.println("After change a is " + a)后,会把a地址的内容输出,当然就是After change a is ok ok?了
    第二例子中,调用change时,把a的引用的值传递进去,change方法内重新创建了一个对象,(注意:该对象的创建不影响方法change外的变量,这可以通过变量的生命周期很容易理解),新的对象的值是40。但是方法体外的变量a的引用和值都没改变,所以输出的值都是10咯
      

  3.   

    对象传的是引用,原生值传的是值!
    ---------------------
    错误!!!!!!! Java里只有按值传递.如果学过C++,  把java中的引用, 当作C++中的指针去理解.
    而C++中的引用则是另外一回事
      

  4.   

    学完了JAVA,才知道被JAVA骗了所谓没有指针, 其实引用就是指针, 只是不能加加减减
    所谓没有虚函数, 其实默认全部是虚函数
      

  5.   

    Java 全都是传值 ,aChinese 说得好,抽象数据类型作为参数就是句柄的复制, 对象没有复制,但是句柄复制了。
      

  6.   

    to : kexsong(阿信) ( ) 信誉:94 第二例子中,调用change时,把a的引用的值传递进去,change方法内重新创建了一个对象,(注意:该对象的创建不影响方法change外的变量,这可以通过变量的生命周期很容易理解),新的对象的值是40。但是方法体外的变量a的引用和值都没改变,所以输出的值都是10咯-----------------------------
    "change方法内重新创建了一个对象 ......" 
    但是语句 ‘arg = new Integer(40); ’ 不是把引用 arg 指向它了吗?
    难道退出函数体后,arg又自动指向原先?
      

  7.   

    “Java里只有按值传递.”很认同。
      

  8.   

    假设对象a的起始地址为1234H,以a为参数,其实传递的是a的地址,我们可以在这个地址里改变内容,但是无法改变这个地址。所以,a的地址始终是1234H,在函数内部实例化一个新类(地址当然不同于1234H)赋给a,也改变不了这个事实。
      

  9.   

    改变下方式,等价于:
     void main() 

      StringBuffer a("ok");   a.print(); //打印
      
      change(&a); 
      
      a.print();//打印
    } void change(StringBuffer* ia)  //a的地址 复制给ia
    {
       ia->append(" ok?"); //ia-> 指向 a 对象 ,所以a.append("ok?") 改变了a的内容
    }
    第二个例子:void main()
      Integer a(10);
      
      printf("Before Change, a is "); 
      a.print();
      
      change(a);
      
      printf("Before Change, a is "); 
      a.print();
    } void change(Integer* arg) // a 地址 复制给 arg (两者独立的)
     {
     
      arg = new Integer(40); // 又将 Integer(40) 的地址 复制给 arg ,因而 a 没变. 
     }
     运行结果是:
    Before Change, a is 10
    After Change a is 10--学习中.
      

  10.   

    对于非基本类型(除int,float等),都是用按值调用。但是由于java访问数据是用指针访问,所以按值调用的值是指针,所以最终的效果是引用调用。对于基本数据,可以被java理解为指向内存地址的数据,所以他们被真正地解释为按值调用。关于此类讨论,可以参考《Thinking in java》一书
      

  11.   

    在java中只有传值,你所说的StringBuffer就是一个对象,它的存的是一个引用,所以按照传值的方式就是把StringBuffer的引用传过去的,所以能改变.但是下面的第2个你是用的基本数据类型,它不是一个对象,(本来在java语言中,可是说是纯面向对象的,但是就只有几种基本数据类型不是面向对象的),同样按传值的方式,也就是说把原来的变量复制了一份,在调用它的函数在另外开辟了一个单元来放它,和原来的那个变量是没有关系的,所以原来的的那个变量的值不会改变。.