首頁 >Java >java教程 >分析java有沒有引用傳遞

分析java有沒有引用傳遞

零到壹度
零到壹度原創
2018-03-19 09:53:181603瀏覽

關於java中呼叫函數時有沒有引用傳遞的問題,一直眾說紛紜。有人說java只有值傳遞,也有人說java既有值傳遞也有引用傳遞,那麼java中到底有沒有引用傳遞呢,下面我來分析一下。

值傳遞:是對所傳遞參數進行一次副本拷貝,對參數的修改只是對副本的修改,函數呼叫結束,副本丟棄,原來的變數不變(即實參不變)  

 引用傳遞:參數傳遞到函數時,不複製副本,而是直接將參數本身傳入到函數,函數內對參數的任何改變都會反映到原來的變數上。

 C++和java都有引用的概念,但在這兩種語言中卻有完全不同的意義。 C++中我們可以用形如"int &b=a」的形式來定義變數a的一個引用b,b只是a的一個別名,b和a在記憶體中佔同一個儲存單元,利用引用機制我們可以在調用函數時實現值的雙向傳遞-即引用傳遞,看下面程式碼: 

 
 示例一 
     #include <iostream> 
     using namespace std;
     int main() 
     {   void swap(int &,int &);
       int i=3,j=5; 
         swap(i,j); 
            cout<<"i="<<i<<"j="<<j<<endl; 
               return 0; 
               } void swap(int &a,int &b)
                 { int temp;
                   temp=a; 
                     a=b;  b=temp;  }
  执行上面的程序输出的是i=5 j=3,a和b传递给swap()函数的时候,是传递的他们本身的地址,不是他们的拷贝,所以在函数中对他们的改变可以直接影响到实参a和b,这就是引用传递。 java中的引用更像C++中的指针,当我们定义一个对象时(比如Person p=new Person()),定义的对象实例会放到java堆中,而变量p(即引用)会放到java栈中,p指向堆中的Person对象实例。
    
    为什么有很多人认为java有引用传递呢?一种情况是有人认为调用函数时其参数有可能是引用(如上面的p),所以java有引用传递,这部分人对引用传递根本没有正确的认识;而另一种情况看似有道理,但是仔细分析也是不正确的的,他们往往会用如下的代码来证明他们的观点: 
    实例二:
    复制代码 class Demo{  
       int a;  
       public Demo(int a){  
           this.a=a;  
       }  
   }  
   public class TestQuote{  
       public static void main(String args[]){  
           Demo d1=new Demo(1);  
           Demo d2=new Demo(2);  
           System.out.println(d1.a);  
           System.out.println(d2.a);  
           function(d1,d2);  
           System.out.println(d1.a);  
           System.out.println(d2.a);  
       }  
       private static void function(Demo d1,Demo d2){  
           int a;  
          a=d1.a;  
           d1.a=d2.a;  
           d2.a=a;  
       }  
   }  
  复制代码 
   他们的观点如下:执行上面的代码,调用function()函数以前输出的结果是1、2,调用function()函数之后输出的结果会是2、1,可见在函数内对d1和d2的改变反映到了原来的变量上,要不是不会输出2、1的。  这种解释是很迷惑人的,看上去好像很正确,下面的代码会很好的反驳上面的观点:
    示例三:
     复制代码  class Demo{  
       int a;  
      public Demo(int a){  
           this.a=a;  
       }  
   }  
   public class TestQuote{  
      public static void main(String args[]){  
          Demo d1=new Demo(1);  
          Demo d2=new Demo(2);  
          System.out.println(d1.a);  
          System.out.println(d2.a);  
          function(d1,d2);  
          System.out.println(d1.a);  
          System.out.println(d2.a);  
      }  
      private static void function(Demo d1,Demo d2){  
          Demo temp;  
          temp=d1;  
          d1=d2;  
          d2=temp;  
      }  
  } 
   执行上面的代码,调用function()前后程序输出的都是1、2,此程序试图通过调用function()交换d1和d2,但是没有成功,为什么呢?因为d1和d2是值传递,function()中的d1和d2是main()函数中d1和d2的副本,调用完function()不会对main()中的变量产生影响。再看示例二中,function()函数内改变的并不是d1和d2本身的值,而是d1和d2指向的对象的值,调用完function()后d1和d2仍然指向函数调用前的堆地址,即函数参数是栈中的d1和d2,而不是堆中d1和d2指向的对象,即使你在函数中改变了堆中的对象,但没有改变函数参数的值。所以示例二并不是什么引用传递;可见java中只有值传递。
   但是网上有很多针对"java值传递和引用传递进行的区别"的文章,如果读者看到的话一定要清楚,其中所说的引用传递是不正确的,他们所说的引用传递就是示例二中的那种情况。不幸的是,网上有很多文章都把示例二中的那样的传递看做引用传递,如果读者看到知道是什么意思就行了。

以上是分析java有沒有引用傳遞的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn