java:参数传递过程初学

来源:互联网 发布:递归算法解决迷宫问题 编辑:程序博客网 时间:2024/05/29 15:50
package com.jvmfinalstatic;//需求分析:本节学习java中参数传递过程://参考文献:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html//参考文献2:http://blog.csdn.net/yangyuankp/article/details/7651251/* * 1.基本类型作为参数传递时: *      基本类型作为参数传递时,传递的是这个值的拷贝。无论你怎么改变这个拷贝,原值是不会改变的。 * 2.对象作为参数传递时: *      当对象作为参数传递时,传递的是对象的引用,也就是对象的地址 * 3.总结: *      无论是基本类型作为参数传递,还是对象作为参数传递,实际上传递的都是值,只是值的的形式不用而已。 *      第一个示例show1()用基本类型作为参数传递时,将栈内存中的值9传递到了change1方法中。第二个示例 *      中用对象作为参数传递时,将栈内存中的值(指向堆内存中对象的地址)传递到了change2方法中。当用对象 *      作为参数传递时,真正的值是放在堆内存中的,传递的是栈内存中的值,而栈内存中存放的是堆内存的地址, *      所以传递的就是堆内存的地址。这就是它们的区别。 * */class Student{    private String name;    private int age;    Student(String name,int age){        this.setName(name);        this.setAge(age);    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}class BaseParaDeli{    private int data = 9;    //int 是基本类型因此执行这句话就会 在栈内存中直接开辟一个内存把9存入;这个内存的"名字"为data;    public String str = "i am eternal";    // 此时,会在常量池种开辟一个内存,在其中存入"i am eternal";并且在栈内存中开辟一个内存"名字"为    //str其中存放的是常量池中"i am eternal"的地址;    public void show1(){        BaseParaDeli bpd = new BaseParaDeli();        bpd.change1(data);        System.out.println("data = "+data);//输出:结果 data = 9;        /* 原因分析: 调用BaseParaDeli对象的change1方法,并且以date为参数。JVM读到这段代码时,检测到         * change1方法中的 x 是局部变量,第一步:在栈中开辟一块空间把x放入其中,并且把date的值赋给x,         * 此时 栈中这个内存的"名字"为x 其中存放的值为 9;第二步:读到x = 100时,把100赋给x;因此,在         * 栈中就会出现两个内存地址 一个名为 data 存放的是9,两一个名为x存放的是100。第三步:change1方         * 法执行完毕,立即释放局部变量 x 所占用的栈空间         *           * */    }    public void show2(){        BaseParaDeli bpd = new BaseParaDeli();        Student stuOne = new Student("John",25);        bpd.change2(stuOne);        System.out.println(stuOne.getName()+" "+stuOne.getAge());//输出: John 25        /* 原因分析:         * 调用bpd对象的change2方法,以引用stuOne为参数。第一步:JVM检测到change2方法中的stu参数为局部变量,         * 立即加入到栈中,由于是引用类型的变量,所以stu中保存的是stuOne中的指针,此时stu和sutOne指         * 向同一个堆中的对象。在stu和stuOne之间传递是指针(引用/ 地址)。 也就是说,在栈内存中有两个地址:一个         * "名字"为stuOne其中存放的是执行堆中对象的地址(比如XXF100);另一个"名字为"stu的内存里面存放的是同一个地址(XXF100)         * 第二步:当读到:stu = new Student("xiaoMing",100);change2方法中又实例化了一个Student对象,并且赋给stu;         * 即:在堆区new了一个对象,并且把该对象的指针保存在栈中的stu对应空间,此时实例stu不再指向实例stuOne所指向的对象,         * 但是实例stuOne所指向的对象并无变化,这样无法对stuOne造成任何影响,因此输出结果为:John 25;         * 第三步:方法执行完毕后,栈中的内存自动释放,堆中的对象等待回收机制回收;         *          * */    }    public void show3(){        BaseParaDeli bpd = new BaseParaDeli();        Student stuOne = new Student("Mike",30);        bpd.change3(stuOne);        System.out.println(stuOne.getName()+" "+stuOne.getAge());//输出: Mike 200        /*原因分析:         * 调用bpd对象的change3方法,以引用stuOne为参数。第一步:JVM检测到change3方法中的stu参数为         * 局部变量,立即加入到栈中,由于是引用类型的变量,所以stu中保存的是stuOne中的指针,此时stu和         * sutOne指向同一个堆中的对象。在stu和stuOne之间传递是指针(引用/ 地址)。 也就是说,在栈内存中         * 有两个地址:一个"名字"为stuOne其中存放的是执行堆中对象的地址(比如XXF100);另一个"名字为"stu的         * 内存里面存放的是同一个地址(XXF100)         * 第二步:stu.setAge(200);其实就是调用stuOne指向的对象的setDay方法,因为两者指向的是同一堆中的对象         * 所以stu对属性的改变会影响到stuOne的属性。         * 第三步:change3方法执行完毕,立即释放局部引用变量stu         */    }    public void show4(){        BaseParaDeli bpd = new BaseParaDeli();        bpd.change4(str);        System.out.println("str: "+str);//输出结果:str: i am eternal        /*原因分析:         * 调用bpd对象的change4方法,以字符串str为参数。第一步:JVM检测到change4方法中的s参数为         * 局部变量,立即加入到栈中,由于是字符串类型的变量,所以s中保存的是str中的指针,此时s和         * str指向常量池中同一个对象。         * 第二步:s = s + "is change ?";其实就是在常量池中再开辟一个内存把s= i am eternal is change ?         * 存入其中,并且将栈中s中存放的地址指向它;这样 在栈中有两个内存 s 和 str 堆中也有两个内存,各自         * 指向各自的,因此str的值不会发生改变;         * 第三步:change4方法执行完毕,立即释放局部引用变量s         *           *  总:String变量和基本数据类型包装类中的那六个是一样的道理:可以参考上篇文章;         *          *          * */    }    public void change1(int x){        x = 100;    }    public void change2(Student stu){        stu = new Student("xiaoMing",100);    }    public void change3(Student stu){        stu.setAge(200);    }    public void change4(String s){        s = s + "is change ?";    }}public class ParameterDelivery {    public static void main(String[] args) {        BaseParaDeli bp = new BaseParaDeli();        bp.show1();        bp.show2();        bp.show3();        bp.show4();    }}
0 0
原创粉丝点击