A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 创出一片辉煌 中级黑马   /  2012-7-28 22:49  /  1935 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

请教一个给方法传递对象的问题
两段代码为什么输出不一样?
(1)
public class Test{
public static void main(String[] args){
  Circle c1=new Circle(1);
  Circle c2=new Circle(2);
  System.out.println("交换前c1.r "+c1.r);
  System.out.println("交换前c2.r "+c2.r);
  swp(c1,c2);
  System.out.println("交换后c1.r "+c1.r);
  System.out.println("交换后c2.r "+c2.r);
}
public static void swp(Circle x,Circle y){
   Circle t=x;
   x=y;
   y=t;
  }
}
class Circle{
double r;
Circle(double radius){
  r=radius;
}
}
以上输出为:
交换前c1.r 1.0
交换前c2.r 2.0
交换后c1.r 1.0
交换后c2.r 2.0
(2)
public class Test{
public static void main(String[] args){
  Circle c1=new Circle(1);
  Circle c2=new Circle(2);
  System.out.println("交换前c1.r "+c1.r);
  System.out.println("交换前c2.r "+c2.r);
  Circle t=c1;
  c1=c2;
  c2=t;
  System.out.println("交换后c1.r "+c1.r);
  System.out.println("交换后c2.r "+c2.r);  
}
}
class Circle{
double r;
Circle(double radius){
  r=radius;
}
}
以上输出为:
交换前c1.r 1.0
交换前c2.r 2.0
交换后c1.r 2.0
交换后c2.r 1.0

5 个回复

倒序浏览
本帖最后由 马进 于 2012-7-29 00:24 编辑

照成偏差的主要问题是,JAVA是按值传递参数的!
如果是基础类型参数,如int,double,String 等,直接传递值,在函数中直接修改,将不会修改到原变量。
如果是对象参数,传递参数的时候,将会传递一个指向该对象引用的副本,也就是说JAVA在传递参数时,先NEW了一个引用,然后再将此引用传递到函数。
这就是为什么会造成对象交换不过来,而在方法中又可以修改成员变量。
  1. public static void swp(Circle x, Circle y) {
  2.                 Circle t = x;
  3.                 x = y;
  4.                 System.out.println(x.r);
  5.                 x.r = 3;
  6.                 y = t;
  7.                 System.out.println(y.r);
  8.         }
复制代码
回复 使用道具 举报

数据加密问题


public class Test1
{
public static void main(String[] args)
{
  Circle c1=new Circle(1 );
  Circle c2=new Circle( 2);
  System.out.println("交换前c1.r "+c1.r);
  System.out.println("交换前c2.r "+c2.r);
   new swp(c1,c2);//这里虽然调用了SWP函数,但是运行结果并没有返回这里;所以
                 //下面的不会打印结果而是报错,要实现该功能有两个方法;1是定义返回值类型函数
     //2:将打印代码放置在调用函数中

  
}
public static void swp(Circle x,Circle y)
{
   Circle t=x;
   x=y;
   y=t;
   System.out.println("交换后c1.r "+c1.r);
  System.out.println("交换后c2.r "+c2.r);
}
}
class Circle
{
double r;
Circle(double radius)
{
  r=radius;
}
}


回复 使用道具 举报
哈哈楼主你被自己骗了。。。
首先你这个方法的参数列表内是两个局部变量,而在调用这个方法时这两个局部变量接收到的是哈希值
这两个变量是指向原来的对象,你又将两个局部变量的哈希值进行了交换,这没错
关键就在于方法交换完事后两个局部变量就不复存在,原来的两个实参变了吗,没有。
不信你在方法内打印两个局部的变量,肯定交换了。这仅仅是局部变量局部的交换,并没有影响到原来的引用。
这就相当于a人牵着a狗,b人牵着b狗。
后来一调用函数
就又来个a1人牵着a狗,b1人牵着b狗
a1对b1说,这狗不好咱换换把,b1答应了
于是a1牵着b狗,b1牵着a狗
后来方法执行完毕
a1说不行我得回家偷菜
b1说不行我也得回去
于是,
a人还是牵着a狗,b人还是牵着b狗
希望对你有所帮助。。。

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
  1. public static void swp(Circle x,Circle y){
  2.    Circle t=x;
  3.    x=y;
  4.    y=t;
  5.   }
  6. }
复制代码
调用这个代码和没调用一样,原先的值又没改变。
我曾经也犯这样的错误
public static void swap(int a,int b){.....}
然后调用swap(arr[0],arr[1]);
其实应该这样public static void swap(int[] arr,int a,int b){....}
swap(arr,0,1);
回复 使用道具 举报
侯宪博 发表于 2012-7-29 01:43
哈哈楼主你被自己骗了。。。
首先你这个方法的参数列表内是两个局部变量,而在调用这个方法时这两个局部变 ...

:funk:厉害,有老毕的风范。哈哈:lol

点评

然后就 O了  发表于 2012-7-29 08:44
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马