面试官爱问的一个基础问题:Java是值传递还是引用传递?

想必大家都对这个问题都有自己的看法,那到底事实是怎样的,我们又该如何回答面试官这个问题呢?今天咱们就来好好分析一波

值传递?引用传递?

首先,我们得先知道什么叫值传递,什么叫引用传递,知道这个才能理解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中用的是值传递(记好咯,下次面试别回答错了)

在其它方法里面改变引用类型的值都是通过引用改变的,当传递引用对象的时候,传递的是复制的引用的对象句柄,是复制过的,也就是在内存中复制了一个句柄,这两个句柄指向同一个对象,所以你改变这个句柄对应的空间的数据会影响到外部的变量

虽然是复制的,但是指向的是同一个地址,当你把这个句柄指向其它对象的引用时并不会改变原来的值(例子三String),因为你用的是复制过的句柄

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

面试官:Java为什么只有值传递?相关推荐

  1. 吊打面试官 | Java到底是值传递还是引用传递

    HI ! 我是小小,我们又见面了,今天是本周的第六篇,这篇主要讲解关于Java到底是值传递还是引用传递. 先说答案 答案为值传递 答案解释 先说一下值传递和引用传递的概念和区别 值传递:是指在调用函数 ...

  2. 面试:Java 到底是值传递还是引用传递?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | Intopass 来源 | zhihu.com ...

  3. 面试官:兄弟,说说Java到底是值传递还是引用传递

    二哥,好久没更新面试官系列的文章了啊,真的是把我等着急了,所以特意过来催催.我最近一段时间在找工作,能从二哥的文章中学到一点就多一点信心啊! 说句实在话,离读者 trust you 发给我这段信息已经 ...

  4. java只有值传递_面试官:为什么 Java 中只有值传递?

    1.为什么 Java 中只有值传递? 首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语.按值调用(call by value)表示方法接收的是调用者提供的值,而按引用调用(ca ...

  5. 死磕面试系列,Java到底是值传递还是引用传递?

    Java到底是值传递还是引用传递? 这虽然是一个老生常谈的问题,但是对于没有深入研究过这块,或者Java基础不牢的同学,还是很难回答得让人满意. 可能很多同学能够很轻松的背出JVM.分布式事务.高并发 ...

  6. 一文彻底搞懂Java中的值传递和引用传递!

    关于Java中方法间的参数传递到底是怎样的.为什么很多人说Java只有值传递等问题,一直困惑着很多人,甚至我在面试的时候问过很多有丰富经验的开发者,他们也很难解释的很清楚. 我很久也写过一篇文章,我当 ...

  7. Java 到底是值传递还是引用传递?

    先说下答案: Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用. 如果参数是基本类型,传递的是基本类型的字面量值的拷贝. 如果参数是引用类型,传递的是该参量所引用的对象在内存中地址 ...

  8. Java中的值传递和引用传递

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?      答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为 ...

  9. Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递?

    来自:沉默王二 在逛 Stack Overflow 的时候,发现了一些访问量像阿尔卑斯山一样高的问题,比如说这个:Java 到底是值传递还是引用传递?访问量足足有 188万+,这不得了啊!说明有很多很 ...

最新文章

  1. 程序界面把程序员这条路走下去
  2. oracle 实现基于函数的索引
  3. SQL CASE WHEN用法
  4. [WPF Bug清单]之(6)——Button的IsCancel属性失效
  5. word中安装MathType
  6. elasticsearch 自定义routing
  7. Python 创建目录文件夹
  8. docker mysql8.0挂载_Docker安装MySQL 8.0.17 并挂载数据及配置文件,修改时区
  9. Ext JS 6学习文档-第8章-主题和响应式设计
  10. AD7124读写驱动
  11. PostMan中文插件支持8.12.2
  12. 购物网站(测试+步骤+代码)
  13. html设置文字在背景图上,css如何实现文字在背景图片之上 css实现文字在背景图片之上代码...
  14. java实现程序等待一段时间的代码
  15. 06: 综合布线 、 子网划分
  16. 怎么恢复计算机误删的用户组,如何恢复误删的用户组
  17. android 壁纸软件 宝宝,宝宝巴士桌面软件下载
  18. html文字显示为单行,双行
  19. 电机控制学习笔记——PMSM数学模型
  20. C语言 将十六进制字符串转为十六进制数 (二进制、十进制都适用)

热门文章

  1. 安卓 linux 街机 dc,DC最强的街机模拟器
  2. 乾坤 微前端_最全汇总之微前端知识和实战(EMP技术方案)
  3. 锐捷ap怎么设置_新房装修网络布线方案一:AC+AP模式,弱电箱只放光猫和集成AC...
  4. AVB2 avbtool.py脚本常用命令
  5. python计算时间装饰器_使用python装饰器计算函数运行时间的实例
  6. 怎么样简单快速的将pdf保存为图片--三部曲
  7. 操作系统之内存管理:3、基本分页存储管理
  8. (软件工程复习核心重点)第四章总体设计-第二节:设计原理
  9. 4-1:C/C++内存管理
  10. python requests 提示警告 InsecureRequestWarning