java:参数传递过程初学

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();

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值