理解Java的參數傳遞

Java的參數傳遞方式就只有一種:值傳遞。
之前在Java的面試題中,就見過這樣一個問題:Java的參數傳遞是值傳遞仍是引用傳遞?其實這題是問那些從C++轉向Java的程序員的,由於在C++中,有一種叫指針的東西,而在Java的世界中,屏蔽了容易讓程序員犯錯的指針(其實內部只是封裝了指針,不少功能的實現其實仍是經過指針的),也所以讓問題變得更加簡單,在Java參數傳遞中,只存在值的傳遞,不存在引用傳遞。
先來看一個例子: 
public class Test {
        public static void main(String[] args) {
            int i = 1 ; 
            Test test = new Test() ; 
            test.change(i) ; 
            System.out.println(i) ; 
         } 
         public void change(int i) {
          i += 2 ;
          System.out.println(i) ;    
        }
}
 
這個程序會依次輸出3和1。這是已經說明了Java的參數傳遞是值傳遞。
值傳遞的意思就是說,參數在傳遞過程當中,傳遞的是參數的一個副本,而不是引用自己。
上面的例子可能不足以說明問題,由於上面的例子傳遞的是基本類型參數,要是引用類型呢?再看下面的例子:
public class Test { 
        public static void main(String[] args) {
            Apple apple = new Apple() ;
            apple.setColor("red") ;
            apple.setSize("10") ;
            Test test = new Test() ;
             test.change(apple) ;
             System.out.println(apple) ;
        }
        public void change(Apple apple) {
          apple.setColor("green") ;
          apple.setSize("20") ;
          System.out.println(apple);
        }
}
 class Apple {
  private String color ;
  private String size ;
  
  public void setColor(String color) {
      this.color = color ;
  }
  public void setSize(String size) {
      this.size = size ;
  }
  public String getColor() {
    return this.color ;
  }
  public String getSize() {
    return this.size ;
  }
  
  public String toString() {
    return "color = " + this.color + ", size = " + this.size ;
  }
}
上面這段程序依次輸出依次輸出:  color = green, size = 20 和   color = green, size = 20 。
有人會說,你看change()方法這不明明是改變了以前的apple對象嗎?這傳遞的難道不是引用?這是初學者最難理解的地方。
這傳遞的還的確是引用,也就是傳遞的apple對象的內存地址;若是不傳遞引用的話,難道還傳遞對象嗎?那效率低得都海枯石爛了!
雖然傳遞的是引用,可是傳遞的是引用的一個副本!這纔是關鍵。再看下面的例子:
public class Test {
        public static void main(String[] args) {
            Apple apple = new Apple() ;
            apple.setColor("red") ;
            apple.setSize("10") ;
            Test test = new Test() ;
            test.change(apple) ;
            System.out.println(apple) ;
            
        }
        public void change(Apple apple) {
          Apple apple2 = new Apple() ;
          apple2.setColor("green") ;
          apple2.setSize("20") ;
          apple = apple2 ;
          System.out.println(apple);
        }
    }
    
 class Apple {
  private String color ;
  private String size ;
  
  public void setColor(String color) {
      this.color = color ;
  }
  public void setSize(String size) {
      this.size = size ;
  }
  public String getColor() {
    return this.color ;
  }
  public String getSize() {
    return this.size ;
  }
  
  public String toString() {
    return "color = " + this.color + ", size = " + this.size ;
  }
 
 }
上面的程序依次輸出: color = green, size = 20 和    color = red, size = 10 。
看出什麼問題了嗎?就是不管怎麼樣都沒法改變引用。這充分說明了一個問題,在參數傳遞過程當中,傳遞的是引用的值,也就是引用的副本。沒有任何方法能改變引用自己!這就是Java參數傳遞方式是值傳遞的含義。深入理解Java的參數傳遞對於排除一些難以發現的bug很是有好處。
相關文章
相關標籤/搜索