黑马程序员技术交流社区

标题: 今天学习所遇到的麻烦 [打印本页]

作者: 创出一片辉煌    时间: 2012-7-28 22:49
标题: 今天学习所遇到的麻烦
请教一个给方法传递对象的问题
两段代码为什么输出不一样?
(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

作者: 马进    时间: 2012-7-29 00:18
本帖最后由 马进 于 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.         }
复制代码

作者: 尹善波    时间: 2012-7-29 01:03
标题: 数据加密问题

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;
}
}



作者: 侯宪博    时间: 2012-7-29 01:43
哈哈楼主你被自己骗了。。。
首先你这个方法的参数列表内是两个局部变量,而在调用这个方法时这两个局部变量接收到的是哈希值
这两个变量是指向原来的对象,你又将两个局部变量的哈希值进行了交换,这没错
关键就在于方法交换完事后两个局部变量就不复存在,原来的两个实参变了吗,没有。
不信你在方法内打印两个局部的变量,肯定交换了。这仅仅是局部变量局部的交换,并没有影响到原来的引用。
这就相当于a人牵着a狗,b人牵着b狗。
后来一调用函数
就又来个a1人牵着a狗,b1人牵着b狗
a1对b1说,这狗不好咱换换把,b1答应了
于是a1牵着b狗,b1牵着a狗
后来方法执行完毕
a1说不行我得回家偷菜
b1说不行我也得回去
于是,
a人还是牵着a狗,b人还是牵着b狗
希望对你有所帮助。。。
作者: 陈汉维    时间: 2012-7-29 02:02
  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 02:04
侯宪博 发表于 2012-7-29 01:43
哈哈楼主你被自己骗了。。。
首先你这个方法的参数列表内是两个局部变量,而在调用这个方法时这两个局部变 ...

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




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2