闲来无事,回忆起大学我与校花同桌的快乐时光,其中有一件特别有意思的事,在此来分享给大家。
大二的某个早晨,眼见着快要上课了,老师上节课布置的编程作业我还没有写完,于是乎想借校花同桌的作业来抄一抄,校花很爽快的答应了,我拿着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.在传递参数不是基本类型时,我们得到了参数的引用地址,修改该地址储存的值时,会对原参数构成影响
3.我们这里不讨论关于“Java中只有值传递”的内容,仅以Java为例来讨论值传递与引用传递,由于Java中没有指针的概念,所以Java引入地址来指向数据实现引用传递
五、后续
Baldwin:哎呀这下我才算是真的明白了,真的太谢谢你了,时间不早了,这下我真的得回去了
校花:这都凌晨三点钟了,寝室门都关了,回不去了,要不今天在宾馆睡吧
Baldwin:没事儿,我带了身份证了,我等下去网吧包夜,你要不要一起去啊?我压缩贼6
校花:WQNMLGB,NGSB

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/39804.html