我与校花同桌之间的金钱交易(又名:戏说值传递与引用传递,这还看不懂你来打我)

闲来无事,回忆起大学我与校花同桌的快乐时光,其中有一件特别有意思的事,在此来分享给大家。

大二的某个早晨,眼见着快要上课了,老师上节课布置的编程作业我还没有写完,于是乎想借校花同桌的作业来抄一抄,校花很爽快的答应了,我拿着U盘COPY了一份校花的代码,把代码导入到我的IDEA里稍加修改,完事儿还删掉了U盘里的代码,然后自信的交上了作业。

下课后校花找到我说“我的作业不能白让你抄,你得付出代价啊,把你的钱包给我,你得请我吃饭”,然后校花拿着我的钱包去食堂刷了四份红烧肉。

下午校花把钱包还给我的时候,我怒了,“就抄你一次作业,你特么刷了劳资四块钱,你是猪么?”

校花白了我一眼说“我又不白刷你饭卡,晚上来**酒店305房,我帮你补习功课,你夜里9点过来,连敲1024下门,我就帮你开门”

我寻思行吧!就当教学费了

吃完晚饭回寝室打游戏打到8:50,我穿上外套,拿着我的笔记本电脑和Java教材跑到**宾馆,敲了三下门,校花就把门打开了。

只见校花穿着半透明睡衣,画着美美的妆站在门口,我当时懵了,道“你还真精致,大半夜的还化妆。你要给我讲什么内容啊?我可是花了四块钱的,你今天要是不给我讲明白了,可得还我钱”

校花迟疑的看着我,愣了好半天才说道“那我今天给你讲讲Java程序中的值传递与引用传递吧!”

一、定义

从字面意义上来说就是Pass By Value 和 Pass By Reference,值传递就是在方法中用到的是参数的值,引用传递就是在方法中获取的是参数的引用的值,通过对引用地址的操作,直接操作这个参数本身。

二、举例

听完定义,我还是很懵逼,校花接下来又讲到:

我们先定义三个类

Baldwin.java类代表你,你的属性里包括你的作业和你的钱

import java.util.HashMap;

/**
 * 类描述
 *
 * @author: 12405
 * @date: 2020/3/17-21:54
 */
public class Baldwin {

    private int myCode;
    private HashMap<String,String> myMoney;

    public int getMyCode() {
        return myCode;
    }

    public void setMyCode(int myCode) {
        this.myCode = myCode;
    }

    public HashMap<String, String> getMyMoney() {
        return myMoney;
    }

    public void setMyMoney(HashMap<String, String> myMoney) {
        this.myMoney = myMoney;
    }
}

Girl.java类代表校花,校花在这次里只涉及到作业的属性

/**
 * 类描述
 *
 * @author: 12405
 * @date: 2020/3/17-21:54
 */
public class Girl {
    private int myCode;

    public int getMyCode() {
        return myCode;
    }

    public void setMyCode(int myCode) {
        this.myCode = myCode;
    }
}

Transaction.java类里面有我们两个进行的操作

import java.util.HashMap;

/**
 * 类描述
 *
 * @author: 12405
 * @date: 2020/3/17-22:20
 */
public class Transaction {


    int baldwinCopyCode(int girlCode){
        //Baldwin得到的传进来的校花的作业
        int myCode;
        //Baldwin修改传进来的校花的作业
        girlCode -= 1;
        myCode = girlCode;
        //把修改好的作业传出去
        return myCode;
    }

    void girlCost(HashMap myMoney){
        //校花花钱
        myMoney.remove("money1");
        myMoney.remove("money2");
        myMoney.remove("money3");
        myMoney.remove("money4");
    }
}

我今天借你抄的作业就是典型的值传递,你在使用我给你的代码是,只是复制了我的作业的值,并没有拿到我作业,实际上我的作业还在我的电脑里,你是接触不到的,你抄作业的行为跟下面的程序类似

1.值传递

import java.util.HashMap;

/**
 * 类描述
 *
 * @author: 12405
 * @date: 2020/3/17-22:29
 */
public class Demo {

    public static void main(String[] args) {
        Baldwin baldwin = new Baldwin();
        //Baldwin没写作业,现在的Code是0
        baldwin.setMyCode(0);

        Girl girl = new Girl();
        //校花同桌写了作业,现在的Code是10
        girl.setMyCode(10);

        Transaction transaction = new Transaction();

        System.out.println("Baldwin`s Code:"+baldwin.getMyCode()+",Girl`s Code :"+ girl.getMyCode());
        //Baldwin将修改好的作业,保存到自己的电脑里
        baldwin.setMyCode(transaction.baldwinCopyCode(girl.getMyCode()));
        System.out.println("Baldwin is copying girl`s code");
        System.out.println("Baldwin`s Code:"+baldwin.getMyCode()+",Girl`s Code :"+ girl.getMyCode());
    }
}

你看这个程序的输出

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=52781:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.man.Demo
Baldwin`s Code:0,Girl`s Code :10
Baldwin is copying girl`s code
Baldwin`s Code:9,Girl`s Code :10

Process finished with exit code 0

你虽然在transcation.copyGirlCode(girlCode)中修改了形参中的的girlCode,我知道你时候还删掉了U盘里代码,你得到的这个参数不过是个形参而已,在你copyGirlCode的操作结束之后,你也释放了U盘空间,这个形参直接就删除了,所以无论你怎么操作,也不过是影响到了你所得到的值而已,与我电脑中的代码无关,所以值传递结束后,我的代码还是是10,而你得到了你想要的9

Baldwin:哦哦我现在明白了值传递的意思了,那引用传递呢?

2.引用传递

引用传递有以下示例

import java.util.HashMap;

/**
 * 类描述
 *
 * @author: 12405
 * @date: 2020/3/17-22:29
 */
public class Demo {

    public static void main(String[] args) {
        Baldwin baldwin = new Baldwin();
        //Baldwin有5块钱
        HashMap<String,String> baldwinMoney = new HashMap<>(16);
        baldwinMoney.put("money1","1");
        baldwinMoney.put("money2","1");
        baldwinMoney.put("money3","1");
        baldwinMoney.put("money4","1");
        baldwinMoney.put("money5","1");
        baldwin.setMyMoney(baldwinMoney);

        Girl girl = new Girl();

        Transaction transaction = new Transaction();

        System.out.println("Girl wants Baldwin's wallet");
        //此时Baldwin还有5块钱
        System.out.println("Baldwin`s money:"+baldwin.getMyMoney().size());
        System.out.println("Girl is spending money");
        transaction.girlCost(baldwin.getMyMoney());
        System.out.println("Baldwin`s money:"+baldwin.getMyMoney().size());

    }
}

在这个里面,我拿到了你的钱包,相当于拿到了你的钱包的引用地址,就可以直接操作你的钱包了,我花了你钱包里的钱,直接影响了你钱包还剩下多少钱,所以你看下程序执行的结果

"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\tools\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=52781:E:\tools\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Workspaces\IdeaProjects\DemoTest\out\production\DemoTest" cn.yzstu.man.Demo
Girl wants Baldwin's wallet
Baldwin`s money:5
Girl is spending money
Baldwin`s money:1

Process finished with exit code 0

你看,这不就只剩一块钱了

Baldwin:哦哦我明白了值传递与引用传递的区别了,现在已经12点钟了,我得回去了,要不然我得室友该担心我了

校花:别别别,时间还早,我们还需要深入交流一下

三、值传递与引用传递的深层原理

到这里你已经明白了值传递与引用传递的不同,但是更重要的是他们的深层原理,表象很重要,但是本质更重要,就像我虽然现在表象上在跟铁柱谈恋爱,其实我的的本质还是喜欢你的

我们的Code是int类型的,也就是基本类型,他的值就直接保存在变量里,我们定义int类型变量时直接会有值存在这个变量里,但是我们定义的myMoney类型的变量就不同,他是HashMap变量中储存的其实只有一个地址你看下面这张图

myMoney变量的值其实是你钱包的地址,一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。

我们获取到对象地址就能就能操作对象,这个对象就是你本身引用的对象,所以我们在方法中操作的对象地址,就是你引用的对象地址,这样我操作完成之后你再看你的属性,也就会发生变化了。

四、总结

1.在传递参数时基本类型参数时,我们得到了这个参数的值,无法对参数本身构成影响,此时发生的叫做“值传递”

2.在传递参数不是基本类型时,我们得到了参数的引用地址,修改该地址储存的值时,会对原参数构成影响

五、后续

Baldwin:哎呀这下我才算是真的明白了,真的太谢谢你了,时间不早了,这下我真的得回去了

校花:这都凌晨三点钟了,寝室门都关了,回不去了,要不今天在宾馆睡吧

Baldwin:没事儿,我带了身份证了,我等下去网吧包夜,你要不要一起去啊?我压缩贼6

校花:WQNMLGB,NGSB

发布了45 篇原创文章 · 获赞 113 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/shouchenchuan5253/article/details/104933703