黑马程序员技术交流社区

标题: 看下代码是值传递还是引用传递,有点晕。 [打印本页]

作者: 李东升    时间: 2012-7-23 13:16
标题: 看下代码是值传递还是引用传递,有点晕。
代码如下
  1. public class People {
  2.         public String name;
  3.         public int age;
  4.        
  5.         public People(String name,int age){
  6.                 this.name=name;
  7.                 this.age=age;
  8.         }
  9. }
复制代码
  1. public class Tm {

  2.         /**
  3.          * @param arg
  4.          */
  5.         public static void main(String[] args) {
  6.                 People people=new People("张三",30);
  7.                 System.out.println(people.name+"今年"+people.age+"岁");
  8.                 md(people);
  9.                 System.out.println(people.name+"今年"+people.age+"岁");
  10.         }
  11.         public static void md(People people){
  12.                 people.age=88;
  13.         }
  14. }
复制代码
结果输出 改变了。
  1. 张三今年30岁
  2. 张三今年88岁
复制代码
不清楚这是按值传递还是按引用传递,从结果来看,是不是按引用传递的?

作者: 党巾水    时间: 2012-7-23 13:27
public class Tm {

        /**
         * @param arg
         */
        public static void main(String[] args) {
                People people=new People("张三",30);
                System.out.println(people.name+"今年"+people.age+"岁");
                md(people);
                System.out.println(people.name+"今年"+people.age+"岁");
        }
        public static void md(People people){
                people.age=88;
        }

}

我觉得上边标红的地方类似于一个setAge方法
public static void setAge(int age){
this.age = age;
}


只不过因为方法没有放在People的类里,应该是把值赋给了age,我觉得是个值传递。
作者: 杨文宇    时间: 2012-7-23 14:12
画图比较好理解点。我都是画图

作者: 杨文宇    时间: 2012-7-23 14:19
杨文宇 发表于 2012-7-23 14:12
画图比较好理解点。我都是画图

不好意思,堆栈两个写反了
作者: 刘奇    时间: 2012-7-23 14:55
当然是按引用传递了,在md函数里修改了作为值传递的people参数,所以main函数最后输出的才是88,如果是值传递函数内的操作是不会影响到main函数里的people的age属性的
作者: 范泰洋    时间: 2012-7-23 18:12
public class People {
        public String name;
        public int age;
        
        public People(String name,int age){
                this.name=name;
                this.age=age;
        }
}
public class Tm {
        /**
         * @param arg
         */
        public static void main(String[] args) {
                People people=new People("张三",30);//这里一new了一个对象,就会根据new People("张三",30)这里面的实参去people
构造函数里面去找相应的构造函数,进行初始化。然后把这个里面的值传给构造函数里面的形式参数,再把接收到的值赋值给this.name本类对
象的name。这个this就是那个对调用,就指向那个对象。
                System.out.println(people.name+"今年"+people.age+"岁");
                md(people);
                System.out.println(people.name+"今年"+people.age+"岁");
        }
        public static void md(People people){//然而这里的两个people,一个是类类型 相当于int类型那种,也就是说后面的那个people的类型就是类类型的。
                people.age=88;//其实这里也是按值传递的
        }
}

作者: 郑枫   [̲̅    时间: 2012-7-23 21:55
{:soso_e117:}   看不懂。。
作者: 李东升    时间: 2012-7-23 22:00
范泰洋 发表于 2012-7-23 18:12
public class People {
        public String name;
        public int age;

可以这么理解么。虽然传递过去的是一个对象,但是改变的是对象里面的属性,而不是对象本身,也就是间接的通过对象来保存修改后的值。
作者: 张頔    时间: 2012-7-23 22:04
这里从始至终都是只有一个people对象,所以是按引用传递

而按值传递的话 至少有两个对象,即两份内存空间,这时就会出现你想改a但是你却改了b
作者: 李东升    时间: 2012-7-23 22:13
张頔 发表于 2012-7-23 22:04
这里从始至终都是只有一个people对象,所以是按引用传递

而按值传递的话 至少有两个对象,即两份内存空间 ...

我有点倾向于值传递。。因为改变的是people的age属性,对people没有改变。
而且改变的时候,是people.age来改变的,是直接赋值。
作者: 艾衍年    时间: 2012-7-23 22:41
是引用传递啊,md方法先找到栈内存中的people存的地址,通过地址找到堆内存里的数据,改变age的值。

所以 引用传递是本质,改变age值是操作。
作者: 肖琦    时间: 2012-7-23 22:51
people变量本身是值传递,只是传递过来后,md方法内的变量people所指向的地址与main方法中people指向的地址是相同的,
所有在md方法内部可以访问到对象的内容,这个改动可以通过在main方法中的people观察到.
希望对你有帮助......

作者: 武庆东    时间: 2012-7-23 23:11
引用传递,是指将栈内存空间的使用权交给多个栈内存空间!
注意栈内存和堆内存的区别和联系!
栈内存一般保存对象的实例对象的堆地址,堆内存保存对象中的属性和方法!




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