您的位置:首页 > 编程语言 > Java开发

由JAVA参数传递引发的对引用的思考

2010-04-19 14:29 405 查看
今天在编写一个快速排序函数,其中想用一个在C++中类似swap功能的函数,结果引发了一系列的问题。

下面是在网上搜到的代码,并在我的本地机上作了运行。   
    
  public   class   ParamTest  
  {  
  public   static   void   main(String[]   args)  
  {  
  /*  
    *Test   1:Methods   can't   modify   numeric   parameters  
  */  
  System.out.println("Testing   tripleValue:");  
  double   percent   =   10;  
  System.out.println("Before:   percent   ="   +   percent);  
  tripleValue(percent);  
  System.out.println("After:   percent   =   "   +   percent);  
   
  /*  
    *Test   2:   Methods   can   change   the   state   of   object    
    * parameters  
  */  
  System.out.println("/nTesting   tripleSalary:");  
  Employee   harry   =   new   Employee("Harry",50000);  
  System.out.println("Before:   salary   ="   +   harry.getSalary());  
  tripleSalary(harry);  
  System.out.println("After:   salary   ="   +   harry.getSalary());  
   
  /*  
    *Test   3:   Methods   can't   attach   new   objects   to    
    * object   parameters  
  */  
  System.out.println("/nTesting   swap:");  
  Employee   a   =   new   Employee("Alice",70000);  
  Employee   b   =   new   Employee("Bob",60000);  
  System.out.println("Before:   a   ="   +   a.getName());  
  System.out.println("Before:   b   ="   +   b.getName());  
  swap(a,b);  
  System.out.println("After:   a   ="   +   a.getName());  
  System.out.println("After:   b   ="   +   b.getName());  
   
  }  
   
  public   static   void   tripleValue(double   x)   //doesn't   work  
  {  
  x   =   3   *   x;  
  System.out.println("End   of   method:   x="   +   x);  
  }  
   
  public   static   void   tripleSalary(Employee   x)   //works  
  {  
  x.raiseSalary(200);  
  System.out.println("End   of   method:   salary   ="   +   x.getSalary());  
  }  
   
  public   static   void     swap(Employee   x,   Employee   y)  
  {  
  Employee   temp   =   x;  
  x   =   y;  
  y   =   temp;  
  System.out.println("End   of   method:   x="   +   x.getName());  
  System.out.println("End   of   method:   y="   +   y.getName());  
  }  
   
   
  }  
   
  结果:  
  Testing   tripleValue:  
  Before:   percent   =10.0  
  End   of   method:   x=30.0  
  After:   percent   =   10.0  
   
  Testing   tripleSalary:  
  Before:   salary   =50000.0  
  End   of   method:   salary   =150000.0  
  After:   salary   =150000.0  
   
  Testing   swap:  
  Before:   a   =Alice  
  Before:   b   =Bob  
  End   of   method:   x=Bob  
  End   of   method:   y=Alice  
  After:   a   =Alice  
  After:   b   =Bob  

这是什么原因呢?分析如下:

对于简单类型,改变参数就是直接对参数赋值。

对于复杂类型,如Integer或封装类型,赋值就是改变了引用,所以当你对它所引用的对象的成员做任何修改都是有效的,

但是如果你像C++中,通过对引用的整个对象操作就是又一次改变了引用。而不是对之前引用的对象做修改。

例如:

void swap(Integer a,Integer b)

{

    Integer c=a;

    a=b;

    b=c;

}

swap(Integer(2),Integer(3));

调用这个函数,形参是对实参的引用,然而,你在函数中又改变了它们的引用位置,并不是赋值,所以实参的值不会改变。

因此如果想写交换函数,最好写成这样:

void swap(int a[],int i,int j)

{

    int z=a[i];

    a[i]=a[j],a[j]=z;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息