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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© abian 中级黑马   /  2013-8-2 23:04  /  1151 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class User {
  2.     String geo;
  3.     public String getGeo() {
  4.                 return geo;
  5.         }
  6.         public void setGeo(String geo) {
  7.                 this.geo = geo;
  8.         }
  9.         public User(String s){
  10.                 geo = s;
  11.         }
  12.         void f(User d){
  13.                 d = new User("d1");
  14.                 d.setGeo("gg");
  15.         }
  16.         public static void main(String[] args) {
  17.                 User dddd = new User("dddd");
  18.                 User qq = new User("qq");
  19.                 qq.f(dddd);
  20.                 System.out.println(dddd.getGeo());
  21.                 System.out.println(qq.getGeo());
  22.         }
  23. }
复制代码

输出是:

dddd

qq

请问高手,为什么是dddd而不是gg,JVM在new对象的时候都做了啥?


评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

5 个回复

倒序浏览
qq.f(dddd);//是传的是User dddd = new User("dddd"), new出来的地址值
你传给了f(User d)方法,d = new User("d1");又new出来一个地址值,会与之前的断开。
故System.out.println(dddd.getGeo())与d.setGeo("gg");没有任何联系
  1. public class Demo {

  2.         public static void main(String[] args) {
  3.                 int x = 3;
  4.                 A a = new A();
  5.                 a.show(x);
  6.                 System.out.println(x);
  7.         }
  8. }

  9. class A {
  10.         void show(int x) {
  11.                 x = 5;
  12.         }
  13. }
复制代码
就如同上面代码一样它输出的是3,这是个是值传递一样,你上面的是引用传参。
一样的道理,一个是值,一个是地址。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
xuaner0719 发表于 2013-8-3 00:46
qq.f(dddd);//是传的是User dddd = new User("dddd"), new出来的地址值
你传给了f(User d)方法,d = new U ...

是的,这是障眼法,具有迷惑性
回复 使用道具 举报
这是内存位置的问题,对象在堆里面,方法在方法区内,局部变量在栈里面,他们之前通过指针具有了联系,
你调用函数的时候,其实是把栈里的指针复制到了方法区内,得到的是一个指针副本,并不是对象本身,
而且你这里操作的也只是是指针副本,并没有对以前的对象进行实际的修改,所以值没有变化.
回复 使用道具 举报
我的看法和二楼一样,简单来说,你使用引用传参的过程中,将引用的内存地址给换掉了,所以无法像正常的引用传参一样,改变原地址的值。
下面我们按照程序运行过程跑一下。
第十七行: User dddd = new User("dddd");         你创建了一个引用:dddd       它指向的内存地址是一个User实例。我们 可以直接称呼他为"dddd"
第十九行:qq.f(dddd);                                      你将"dddd"的引用传给了方法void f(User d)中的参数d,该User对象"dddd"就有了两个引用--dddd和d。
第十三行:d = new User("d1");                          这里是又创建了一个叫做"d1"的实例,并且把该实例的引用赋予了d。这样,d就不再指向原来的"dddd"了。
第十四行:d.setGeo("gg");                                此时d指向的是"d1"实例,修改的是"d1"的属性值。而原来的dddd指向的"dddd"不受影响。
这样就说明了,就是因为第十三行的关系,才将原来的引用传参改变了。程序变一下 ,就恢复正常了:
  1. public class User {
  2.     String geo;
  3.     public String getGeo() {
  4.                 return geo;
  5.         }
  6.         public void setGeo(String geo) {
  7.                 this.geo = geo;
  8.         }
  9.         public User(String s){
  10.                 geo = s;
  11.         }
  12.         void f(User d){

  13.                 d.setGeo("gg");
  14.         }
  15.         public static void main(String[] args) {
  16.                 User dddd = new User("dddd");
  17.                 User qq = new User("qq");
  18.                 qq.f(dddd);
  19.                 System.out.println(dddd.getGeo());
  20.                 System.out.println(qq.getGeo());
  21.         }
  22. }
复制代码
其实只是去掉了第十三行而已。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马