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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 邓超军 中级黑马   /  2012-7-17 11:49  /  1684 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class JavaApp {
  2.         public static void main(String[] args) throws Exception
  3.     {
  4.                     Yinyong ya=new Yinyong("Zhangsan");
  5.                     Yinyong yb=new Yinyong("Lisi");
  6.                     swap(ya,yb);//众所周知,类是引用类型,为什么这个函数无效?
  7.                     System.out.println("a="+ya.name+" b="+yb.name);
  8.                     Change(ya);//而这个函数却有效?
  9.                     System.out.println(ya.name);
  10.     }
  11.        
  12.         public static void swap(Yinyong y1,Yinyong y2)
  13.         {
  14.                 Yinyong temp=y1;
  15.                 y1=y2;
  16.                 y2=temp;
  17.         }
  18.        
  19.         public static void Change(Yinyong y)
  20.         {
  21.                 y.name="Wangwu";
  22.         }
  23.        
  24. }

  25. class Yinyong
  26. {
  27.         String name;
  28.         Yinyong(String name)
  29.         {
  30.                 this.name=name;
  31.         }
  32. }
复制代码

4 个回复

倒序浏览
public class JavaApp {
        public static void main(String[] args) throws Exception
    {
                    Yinyong ya=new Yinyong("Zhangsan");
                    Yinyong yb=new Yinyong("Lisi");
                    swap(ya,yb);//众所周知,类是引用类型,为什么这个函数无效?//参数调用是值调用而不是引用调用,这里是把ya和yb的值传给了
                                                                       //swap的形参,但是ya和yb并没有改变。
                    System.out.println("a="+ya.name+" b="+yb.name);
                    Change(ya);//而这个函数却有效?//因为这个函数改变了对象的属性,是对象的属性值变了,但是ya并没有改变                    System.out.println(ya.name);
    }
        
        public static void swap(Yinyong y1,Yinyong y2)
        {
                Yinyong temp=y1;
                y1=y2;
                y2=temp;
        }
        
        public static void Change(Yinyong y)
        {
                y.name="Wangwu";
        }
        
}

class Yinyong
{
        String name;
        Yinyong(String name)
        {
                this.name=name;
        }
}
回复 使用道具 举报
本帖最后由 黑马刘涛 于 2012-7-17 12:07 编辑

java里是传值。
  1. package com.itcast.test;

  2. public class JavaApp {

  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. // TODO Auto-generated method stub
  8. Yinyong ya=new Yinyong("Zhangsan");

  9. Yinyong yb=new Yinyong("Lisi");

  10. swap(ya,yb);//众所周知,类是引用类型,为什么这个函数无效?

  11. System.out.println("a="+ya.name+" b="+yb.name);

  12. Change(ya);//而这个函数却有效?

  13. System.out.println(ya.name);

  14. }



  15. public static void swap(Yinyong y1,Yinyong y2) //将ya,yb的值传给了局部变量y1,y2,结果只是y1,y2交换了值,这两个变量在函数生命期结束时结束。

  16. {

  17. Yinyong temp=y1;

  18. y1=y2;

  19. y2=temp;

  20. }



  21. public static void Change(Yinyong y)

  22. {

  23. y.name="Wangwu";

  24. }
  25. }



  26. class Yinyong

  27. {

  28. String name;

  29. Yinyong(String name)

  30. {

  31. this.name=name;
  32. System.out.println(this.name);

  33. }

  34. }


复制代码
修改一下:
  1. package com.itcast.test;

  2. public class JavaApp {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub
  8.         Yinyong ya=new Yinyong("Zhangsan");

  9.         Yinyong yb=new Yinyong("Lisi");

  10.         //swap(ya,yb);//众所周知,类是引用类型,为什么这个函数无效?
  11.         
  12.         Yinyong temp = ya;
  13.         ya = yb;
  14.         yb = temp;
  15.         System.out.println("a="+ya.name+" b="+yb.name);

  16.         Change(ya);//而这个函数却有效?

  17.         System.out.println(ya.name);

  18.     }

  19.         

  20.     /*public static void swap(Yinyong y1,Yinyong y2) //将ya,yb的值传给了局部变量y1,y2,结果只是y1,y2交换了值,这两个变量在函数生命期结束时结束。

  21.     {

  22.             Yinyong temp=y1;

  23.             y1=y2;

  24.             y2=temp;

  25.     }
  26.     */

  27.    

  28.     public static void Change(Yinyong y)

  29.     {

  30.             y.name="Wangwu";

  31.     }
  32. }



  33. class Yinyong

  34. {

  35.         String name;

  36.         Yinyong(String name)

  37.         {

  38.                 this.name=name;
  39.                 System.out.println(this.name);

  40.         }

  41. }

复制代码
回复 使用道具 举报
这个问题是对象指针局部改变而实际对象指针没变的问题。
在swap(),你的操作是将ya指向了存放Lisi的对象,而yb指向了存放Zhangsan的对象。这个操作是成功的!
但当这个函数swap()结束时,上述操作由于是在函数内进行,在函数外是没有改变的。也就是在内存中开辟了两个指针进行操作,结束时释放了。

而下一个函数change()成功是因为它操作的是yb指针所指向对象的内容,改变的是实际内容,程序结束时,内容已经改变。

swap()函数建议修改:
public static void swap(Yinyong y1,Yinyong y2)
        {
                String temp=y1.name;
                y1.name=y2.name;
                y2.name=temp;
        }

评分

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

查看全部评分

回复 使用道具 举报
       因为Java里方法参数的传递实际上只有值传递(不管基本类型或引用类型),对基本类型来说是把其值传递了一份过去,而对引用类型来说实际是把引用地址的值复制一份传递了过去。
      另外,只有用new方法创建的对象的实际成员数据是存放在堆里面的,而其他方法内部定义的变量都存放在栈中,一旦出了方法的范围就失效,会被内存回收。
       知道了以上两点,就可以分析了,swap方法里y1,y2,temp都是存放在栈里的只保存引用类型地址的变量,不管他们怎么交换,实际上不会改变堆里面的内容,而main方法里的ya, yb的引用类型虽然其地址仍在栈中,而实际数据在堆中,程序中没有任何改变其内容的语句,因此,不会产生交换。

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马