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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. class swapDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Integer a = 5, b = 8;
  6.                 swap(a,b);
  7.                 System.out.println(a.intValue()+"--"+b.intValue());

  8.                 myInt c = new myInt(6);
  9.                 myInt d = new myInt(9);
  10.                 swap(c,d);
  11.                 System.out.println(c.x+"--"+d.x);
  12.         }

  13.         public static void swap(Integer a, Integer b)
  14.         {
  15.                 int temp = a.intValue();
  16.                 a = new Integer(b.intValue());
  17.                 b = new Integer(temp);
  18.         }

  19.         public static  void swap(myInt a, myInt b)
  20.         {
  21.                 int temp = a.x;
  22.                 a.x = b.x;
  23.                 b.x = temp;
  24.         }
  25. }

  26. class myInt
  27. {
  28.         public int x;
  29.         myInt(int x)
  30.         {
  31.                 this.x = x;
  32.         }
  33. }
复制代码
结果:5--8   9--6   
为什么自定义类的成员变量可以改变,Integer类的却不行呢?搞不懂啊,求解

7 个回复

倒序浏览
Integer a = 5, b = 8;是通过自动装箱的,在-128到127之间的数值,是不会通过new在堆内存中为对象分配空间,而是:
 public static Integer valueOf(inti){
finalintoffset=128;if(i>=-128&&i<=127){//must cache
return Integer Cache.cache[i+offset];}
return new Integer(i);}
而你在交换函数中又通过new来分配,在交换函数内部你可以看到确实交换了数值,但不会传递给外部的a,b.而你自己定义的都是通过new 来分配的,交换之后的值传递到了外部。

回复 使用道具 举报
Kristy_Li 发表于 2012-6-8 22:31
Integer a = 5, b = 8;是通过自动装箱的,在-128到127之间的数值,是不会通过new在堆内存中为对象分配空间 ...

a和b的值改128、129结果还是没有交换啊
回复 使用道具 举报
因为对于你的自定义类来说,成员变量是基本数据类型,赋值就会被改变。
但对于Integer来说
public static void swap(Integer a, Integer b)//这里引用a指向内存中一块地址,里面装着值5,b指向内存中一块地址,里面装着值5
        {
                int temp = a.intValue();//temp赋值为5
                a = new Integer(b.intValue());//引用a被指向新位置,里面装着值8
                b = new Integer(temp);//引用b被指向新位置,里面装着5.
        }//注意,此方法里的a和b都是局部变量,在方法体内部被指向新位置了,出了这个方法,a和b就无法访问了,会被垃圾回收器收拾掉。
System.out.println(a.intValue()+"--"+b.intValue());//这里的a和b指向的内存中的地址里的值从未被修改过,自然不会变。
回复 使用道具 举报
何旭栋 发表于 2012-6-8 22:36
a和b的值改128、129结果还是没有交换啊

在这里,a,b是引用类型,而你自定义的虽然也是引用类型,但你交换的时候交换的是引用类型指向的内存空间里面的某一个变量来进行交换a.x和b.x,但是在a,b交换的时候你直接用的是a=...和b=...,所以交换的值不能传递出去
回复 使用道具 举报
在java中,方法参数的传递都是使用的值传递;
首先integer类型传递的是该数值本身,所以在swap方法中又将两个数分别赋给新的两个数
交换的是在方法内部的两个数的值,方法出栈后方法中的两个数值相应的内存被释放
但是开始的两个数值始终没有改变。

自定义类型的swap方法,传递的是自定义类型的内存地址,相当于c中的指针
swap方法改变的是相应内存地址的内容,因此当再访问该地址中的内容时,
内容已经改变了
回复 使用道具 举报
我说说我的理解,
首先要说的是,我感觉这个问题和自动装箱和拆箱没啥联系。
  1.   public static void swap(Integer a, Integer b)//这里只是把a、b的引用复制到这个函数内,
  2.                                                                                          //方法外部的a,b还是指向原来的对象
  3.     {
  4.             int temp = a.intValue();
  5.             
  6.             //这里是改变了a、b的指向,并没有对a、b原来的对象做任何操作。
  7.             a = new Integer(b.intValue());
  8.             b = new Integer(temp);
  9.             
  10.     }//程序运行到这里,swap方法中的局部局部变量都会被释放掉
  11.      //所以,这段代码没有对main方法中的对象做任何操作。


  12.     public static  void swap(myInt a, myInt b)
  13.     {
  14.             int temp = a.x;
  15.             //这里就不同了,这里直接操作的是a、b指向的对象,把对象中的内容改变了
  16.             //当然,这个方法运行完之后,a、b的指向还是原来的对象。
  17.             a.x = b.x;
  18.             b.x = temp;
  19.     }
复制代码
回复 使用道具 举报
public static void swap(Integer a, Integer b)
        {
                int temp = a.intValue();
               // a = new Integer(b.intValue());
                a = b;
               // b = new Integer(temp);
                b = temp;
        }

这个函数之所以不能交换值是因为Integer会自动装箱和拆箱成int类型的,而它是基本类型的对象,基本类型对象在进行函数参数传递时是以值传递的,也就是说在调用swap(Integer , Integer)这个函数时,实参a 和b 分别复制了一个值给函数swap(Integer , Integer)的形参,所以不管a 和b 的值在函数内部如何改变,都没有改变实参的值。
public static  void swap(myInt a, myInt b)
        {
                int temp = a.x;
                a.x = b.x;
                b.x = temp;
        }
这个函数能交换是因为它的参数是类类型的对象,而类类型的对象在进行参数传递时是以地址传递的,而myInt 是一个类类型的对象,调用swap(myInt a, myInt b)后,a 和b 指向的地址中的值已发生了改变,所以这个函数能交换实参的值。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马