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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张庚 中级黑马   /  2013-2-3 15:19  /  2088 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张向辉 于 2013-2-5 12:22 编辑

//基本数据类型参数传递
class Demo
{
        public static void main(String[] args)
        {

                int x = 3;
                show(x);
                System.out.println("x="+x);
        }
        public static void show(int x)
        {
                x = 4;
        }
}

//引用数据类型参数传递
class Demo
{
        
        public static void main(String[] args)
        {
                String x="3";
                show(x);
                System.out.println("x="x);
        }
        public static void show(String  x)
        {
                x ="4";
        }
}

为什么上边那段代码运行打印结果是4
而下面这段打印时3    很费解??  

点评

提问之前自己应先运行下,这两段代码修正语法错误后结果都是3.  发表于 2013-2-3 16:21

12 个回复

倒序浏览
说明String类型数据,一旦定义,其内容是不变的,就是他的指向。
回复 使用道具 举报
呵呵,首先我要给你纠正一下,上面的会输出3,下面的代码才会输出4。
回复 使用道具 举报
     朋友,不好意思,我看错了。上下两段代码都会输出3,在学习引用类型的数据的参数传递时,不要使用String来使得自己糊涂。你稍等我一下。我一会儿贴出代码来讲解两者传递的差别。
回复 使用道具 举报
你越说我越糊涂了
回复 使用道具 举报
下面方法不是改变它的值了吗  怎么没用啊??
回复 使用道具 举报
上面的输出是3这个应该很好理解,下面主要说一下String类型的存储,例如我们定义一个String s="3",这里的s存在栈内存中而在堆中建立了一个String的对象存放数据“3”,然后把数据的地址0x0012赋给栈中的s。当show()使用的时候也是向函数传递的是0x0012这个地址值,也就是在操作同一个对象,当函数将值改为“4”时,堆中的数据自然也就变成了“4”,打印出的值也就是“4”。
(不太会插入图片这里上传成附件,希望这个草图对你有帮助)

demo.png (15.5 KB, 下载次数: 47)

demo.png
回复 使用道具 举报
class Student {
        int age;
        String name;
    public Student(int age,String name)
    {
            this.age=age;
            this.name=name;
    }
}

public class Demo {
        // 基本数据类型参数传递
        public static void changeJiBen(int x) {
                x = 520;
        }
        //引用数据类型参数传递
        public static void changeYinYong(Student s) {
                s.age=101;
        }

        public static void main(String[] args) {
                int x = 250;
                Student s=new Student(23,"Keyee");
                changeJiBen(x);
                changeYinYong(s);
                System.out.println("x=" + x);
                System.out.println("s.age=" + s.age);

        }
    /*
     * 我们可以看到输出x=250,s.age=101。其实只要搞清楚了传递参数的
     * 规则,就不难理解。在主函数中调用changeJiBen时,并没有把存放
     * 在main方法栈区的x的地址传递给changeJiBen的形参,而是传递了
     * 250这个整数值,也就是一旦调用了该方法,形参整数的值就变为250。
     * 而这个形参存放在changeJiBen的方法栈区内,如果在改变其值,与
     * main方法里的x不会有任何关系。那为什么传递Student这个引用对象
     * 却能修改呢。这就很有趣了。在main方法里建立了Student对象后,引
     * 用对象s存放在main栈区里,s并没有存放实际的数据,它是一个指针。
     * 它指向了堆内存里的实际的Student对象,这个对象存放了age=23,
     * name="Keyee"。在调用changeYinYong时,形参得到的是实际对象
     * 在堆内存的地址,也就是形参和main里的s指向了同一块堆内存,两个
     * 方法操作同一份数据,当然可以看到其改变。
     * 本来应该上图的,时间有点仓促。不知这样讲,是否够详细。如果不详
     * 细,我再整理一下。把图也画出来,写成日志。顺便也解释一下你传递
     * String的疑惑。
     *
     */
}

评分

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

查看全部评分

回复 使用道具 举报
我的楼上就提供了很好地解释方法。传递参数一块儿,不仅要看视频,还要看书。书中配有参数传递中的图解。c语言和java的较好的书籍,都会画一定的篇幅来讲解参数传递,例如这一块我推荐看看李刚的《疯狂java讲义》,对这个知识点有很详细的图解,认真看后就会很好地理解。
回复 使用道具 举报
我感觉讲得还不够透彻清晰,我会专门写成日志,和大家交流交流。
回复 使用道具 举报
你参考一下这位师兄的http://bbs.itheima.com/thread-36998-1-1.html
回复 使用道具 举报
Java是按值传递的,传递的是字节拷贝。形参的生存范围只在方法体里。你把形参和实参搞成一样的名字迷惑自己,他俩名字看着一样,但是是两个变量。
对象引用就像对象的遥控器,“.”操作符就像按下遥控器的按钮。
第一个例子,你的形参叫 x 还是叫 y 没有任何区别,都只是把实参的值 3 拷贝一份给形参。就像你拷了我的作业,你在你拷的作业上修改,影响不到我的作业。
第二个例子,x 是一个遥控 string 类型的遥控器,形参 x 是另一个遥控器,你调用方法show()的时候,让一个遥控器也指向了另一个遥控器的遥控对象,但是,你的 x = "4","4"是一个新电视,你只是让形参遥控器 x 又指向了新电视而已,没有“.”运算符你就没有按下遥控器的按钮,也就无法遥控第一个电视了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马