重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章给大家介绍Java中只有值传递的原因是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
10余年的当雄网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整当雄建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联公司从事“当雄网站设计”,“当雄网站推广”以来,每个客户项目都认真落实执行。
首先,我们得先知道什么叫值传递,什么叫引用传递,知道这个才能理解Java到底如何做的。若想理解这两种传递需要先理解形式参数和实际参数两个概念
形式参数:定义函数时使用的参数,用来接收函数传入参数,比如我们写个函数,函数中的参数为形式参数
public void test(String str) { //str为形式参数 System.out.println(str); }
实际参数:我们调用函数时,函数名后面括号中的参数称为实际参数,如下面例子所示
public static void main(String[] args) { A a = new A(); a.test("chengxukong");//chengxukong则为实际参数 }
可以发现,当调用一个有参函数的时候,会把实际参数传递给形式参数;于是这个传递的过程便有两种情况,即值传递和引用传递
值传递就是把参数的值给你,调用函数时将实际参数复制一份传递到函数中,这样函数内部对参数内部进行修改不会影响到实际参数;而引用传递就不一样了,它直接把参数的实际地址给调用函数了,函数内部可直接修改该地址内容,会影响到实际参数
我来举个例子,我司有一个数据库A,仅允许内部人员操作,现在有个项目需要和别的公司合作,该数据库的数据需要交给合作公司一份,我总不能直接把我司数据库A地址给他们,让他们直接连我们数据库A吧,他们要是删库跑路了,那我boss岂不要杀我祭天了
所以这个时候,把我司数据库表数据拷贝一份到一个新的数据库B,合作公司可以看这个数据库B数据,他们也可以随意操作,不会影响我司数据库
这个操作就类似于值传递,如果合作公司直接操作我司数据库,就类似于引用传递了,这下大家应该晓得两者之别了
Java值传递还是引用传递?
我们了解了值传递和引用传递的概念,那Java中到底是哪种传递方式呢?我们来看代码分析
public static void main(String[] args) { Fans fans = new Fans(); int t = 1; fans.test(t); System.out.println("In main:" + t); } public void test(int t) { t = 2; System.out.println("In test:" + t); } //输出 In test:2 In main:1
上述代码,在main中定义t的值是1,在函数test中修改了参数t的值为2,这个结果是不是很容易分析出来了呢?test函数并未改变传入的t的值,那按照上面我们的介绍是不是可以得出结论:Java中是值传递
有的人可能会质疑,你传入的参数t是基本类型,你若传入引用对象类型,那肯定就会改变对象内容了,OK,再来看一段引用类型代码
int a = 10; String b = "fans"; public void test(Fans fans) { fans.a = 20; fans.b = "newFans"; System.out.println("In test,A:" + fans.a+",B:"+fans.b); } public static void main(String[] args) { Fans fa = new Fans(); fa.test(fa); System.out.println("In main,A:" + fans.getA()+",B:"+fans.getB()); } //输出 In test,A:20,B:newFans In main,A:20,B:newFans
哎啊,输出结果竟然一样了,也就是传入的fans对象被函数test修改了,那这样是不是又变成了引用传递了?
于是得出结论,基本类型是值传递,引用类型是引用传递?事实是这个样子吗,我们再来通过String这个引用类型实验下
public void test(String t) { t = "BBB"; System.out.println("In test:" + t); } public static void main(String[] args) { Fans fans = new Fans(); String tt = "AAA"; fans.test(tt); System.out.println("In main:" + t); } //输出 In test:BBB In main:AAA
啊,这,咋肥事,传递的参数值并未修改,怎么又变成值传递了
上述三个例子表现结果各有差异,到底结论是什么呢?一起来分析下
第一个传入的是基本类型,基本类型指向的就是数值,传递类似于赋值操作,不会对原数值产生影响,就是类似于a=10,b=a,b=20这种,并不会使a变为20;
第二个引用对象传入的是引用类型fans的地址的值,传入的原参数fa指向地址0x123456,所以函数test的参数fans也指向0x123456,函数内部对引用fans进行修改,于是修改了0x123456地址的值,造成外部改变
第三个引用对象是String类型,同样传入的是原参数tt的指向地址0x123456,函数test参数t也是指向0x123456的值,那为什么这个和第二个结果不一样的嘞?重点在于 t="BBB"; 这一句本来想尝试着使内容"AAA"改变成"BBB",但是无奈,String类型是static final类型的,这个大家应该晓得的不,不晓得的该去补课读读String的源码了,于是变成了 t=new String("BBB"),t指向了另一个地址,这个地址的内容是"BBB",所以原来的引用tt还是指向原来的地址0x123456,并未改变
有的同学可能会提出问题了,为什么第二个可以改变这个地址的内容,第三个不行?很明显啊,String是final的,不可修改,而第二个可以直接修改该地址的内容;那问题又来了,既然这样,还能叫值传递吗?
告诉你,就是值传递,因为我们第二个的验证方法不对,你如果在函数的第一行加上个fans = new Fans();你看看它还输出啥,这就变成和第三个String类似的道理了,改变了函数参数的指向位置,函数外部和函数内部输出就不一样了,函数内部也就不会影响外部了;如果按照应引用传递,即使加了这一句,也应该是函数内外都是输出一样的,况且,这也有悖于引用传递的会改变传入参数的概念
关于Java中只有值传递的原因是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。