如何理解Java方法的参数只有值传递

学完C++再学Java就像啃完玉米棒再咬棉花糖一样,总有点幸福来得太突然在风中凌乱的感觉。好吧,我们知道,在C++中有值传递和引用传递之分,本人一开始以为Java除了值传递也有引用传递,例如:

//这里为了方便,将变量count公有化
public class Demo {
  public int count=0;
  public static void test(Demo demo,int value)
  {
    ++value;
    ++demo.count;
  }
  public static void main(String[] args) {
        int v=100;
        Demo demo1=new Demo();
        Demo.test(demo1, v);
        System.out.println("demo1.count="+demo1.count);
        System.out.println("v="+v);
  }
}

输出结果是:
demo1.count=1
v=100

可以发现,v的值没有改变,是值传递。对象demo1作为参数传进test方法后,参数demo是对象demo1的引用,可以在方法里影响外部对象demo1的状态,似乎是引用传递。

但是我错了!看看这个反例:

public class Demo {
  public int count=0;
  //交换两个对象
  public static void swap(Demo x,Demo y)
  {
    Demo temp=y;
    x=y;
    y=x;
  }
  public static void main(String[] args) {
        Demo demo1=new Demo();
        demo1.count++;
        Demo demo2=new Demo();
        System.out.println("交换前:");
        System.out.println("demo1="+demo1.count);
        System.out.println("demo2="+demo2.count);
        swap(demo1,demo2);
        System.out.println("交换后:");
        System.out.println("demo1="+demo1.count);
        System.out.println("demo2="+demo2.count);
  }
}

输出结果是:
交换前:
demo1=1
demo2=0
交换后:
demo1=1
demo2=0

如果是引用传递,那么这两个对象会被成功交换,但事实上并没有,说明是值传递。
实际上,Java比我们想象中还要简单(也不简单,应该说没想象中那么复杂( ˇˍˇ )),无论是基本类型还是对象作为参数,都是将它们的拷贝传进去的,即基本类型的拷贝或引用的拷贝,将test()方法改成下面的样子(与上面算是等价)就能清楚看到对象作为参数也是值传递。

public static void swap(Demo x,Demo y)
{
    Demo A=x;
    Demo B=y;
    Demo temp=A;
    A=B;
    B=temp;
}

变量A,B的作用域在test()方法中,在方法结束时变量A和B就被销毁,同样形参x,y在方法结束时就会被丢弃,所以并没有交换实参的引用,这就很容易理解为何Java方法参数没有引用传递,只有值传递。

【2016-04-07 16:35:19】

发表评论

电子邮件地址不会被公开。 必填项已用*标注