理解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很是有好处。
相关文章
相关标签/搜索