什么是值传递,什么是引用传递?

article/2025/9/13 0:00:23

1、什么是值传递,什么是引用传递?

  • 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
  • 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

2、值传递和引用传递的区别是什么?

在这里插入图片描述

3、Java中只有值传递

3.1 纠正一下大家以前的那些错误看法

错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递

错误理解二:Java是引用传递。

错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。

3.2求值策略

我们说当进行方法调用的时候,需要把实际参数传递给形式参数,那么传递的过程中到底传递的是什么东西呢?

这其实是程序设计中**求值策略(Evaluation strategies)**的概念。

在计算机科学中,求值策略是确定编程语言中表达式的求值的一组(通常确定性的)规则。求值策略定义何时和以何种顺序求值给函数的实际参数、什么时候把它们代换入函数、和代换以何种形式发生。

求值策略分为两大基本类,基于如何处理给函数的实际参数,分为严格的和非严格的。

3.3 严格求值

在“严格求值”中,函数调用过程中,给函数的实际参数总是在应用这个函数之前求值。多数现存编程语言对函数都使用严格求值。所以,我们本文只关注严格求值。

在严格求值中有几个关键的求值策略是我们比较关心的,那就是传值调用(Call by value)、传引用调用(Call by reference)以及传共享对象调用(Call by sharing)

1.传值调用(值传递):在传值调用中,实际参数先被求值,然后其值通过复制,在传递给被调函数的形式参数。因为形式参数拿到的只是一个"局部拷贝",所以如果在被调函数中改变了形式参数的值,并不会改变实际参数的值。

2.传引用调用(引用传递)在传引用调用中,传递给函数的是它的实际参数的隐式引用而不是实参的拷贝。因为传递的是引用,所以,如果在被调函数中改变了形式参数的值,改变对于调用者来说是可见的。

3.传共享对象调用(共享对象传递)传共享对象调用中,先获取到实际参数的地址,然后将其复制,并把该地址的拷贝传递给被调函数的形式参数。因为参数的地址都指向同一个对象,所以我们也称之为"传共享对象",所以,如果在被调函数中改变了形式参数的值,调用者是可以看到这种变化的。

不知道大家有没有发现,其实传共享对象调用和传值调用的过程几乎是一样的,都是进行"求值"、“拷贝”、“传递”。你品,你细品。

但是,传共享对象调用和内传引用调用的结果又是一样的,都是在被调函数中如果改变参数的内容,那么这种改变也会对调用者有影响。你再品,你再细品。

那么,共享对象传递和值传递以及引用传递之间到底有很么关系呢?

对于这个问题,我们应该关注过程,而不是结果,因为传共享对象调用的过程和传值调用的过程是一样的,而且都有一步关键的操作,那就是"复制",所以,通常我们认为传共享对象调用是传值调用的特例

我们先把传共享对象调用放在一边,我们再来回顾下传值调用和传引用调用的主要区别:

传值调用是指在调用函数时将实际参数复制一份传递到函数中,传引用调用是指在调用函数时将实际参数的引用直接传递到函数中。

在这里插入图片描述

3.3 java 的求值策略

前面我们介绍过了传值调用、传引用调用以及传值调用的特例传共享对象调用,那么,Java中是采用的哪种求值策略呢?

很多人说Java中的基本数据类型是值传递的,这个基本没有什么可以讨论的,普遍都是这样认为的。

但是,有很多人却误认为Java中的对象传递是引用传递。之所以会有这个误区,主要是因为Java中的变量和对象之间是有引用关系的。Java语言中是通过对象的引用来操纵对象的。所以,很多人会认为对象的传递是引用的传递。

而且很多人还可以举出以下的代码示例:

输出结果:

print in pass , user is User{name=‘hollis’, gender=‘Male’}
print in main , user is User{name=‘hollischuang’, gender=‘Male’}:

可以看到,对象类型在被传递到pass方法后,在方法内改变了其内容,最终调用方main方法中的对象也变了。

所以,很多人说,这和引用传递的现象是一样的,就是在方法内改变参数的值,会影响到调用方。

但是,其实这是走进了一个误区。

**其实Java中使用的求值策略就是传共享对象调用,也就是说,Java会将对象的地址的拷贝传递给被调函数的形式参数。**只不过"传共享对象调用"这个词并不常用,所以Java社区的人通常说"Java是传值调用",这么说也没错,因为传共享对象调用其实是传值调用的一个特例。

值传递和共享对象传递的现象冲突吗?

看到这里很多人可能会有一个疑问,既然共享对象传递是值传递的一个特例,那么为什么他们的现象是完全不同的呢?

难道值传递过程中,如果在被调方法中改变了值,也有可能会对调用者有影响吗?那到底什么时候会影响什么时候不会影响呢?

其实是不冲突的,之所以会有这种疑惑,是因为大家对于到底是什么是"改变值"有误解。

我们先回到上面的例子中来,看一下调用过程中实际上发生了什么?

在这里插入图片描述

在参数传递的过程中,实际参数的地址0X1213456被拷贝给了形参。这个过程其实就是值传递,只不过传递的值得内容是对象的应用。

那为什么我们改了user中的属性的值,却对原来的user产生了影响呢?

其实,这个过程就好像是:你复制了一把你家里的钥匙给到你的朋友,他拿到钥匙以后,并没有在这把钥匙上做任何改动,而是通过钥匙打开了你家里的房门,进到屋里,把你家的电视给砸了。

这个过程,对你手里的钥匙来说,是没有影响的,但是你的钥匙对应的房子里面的内容却是被人改动了。

也就是说,Java对象的传递,是通过复制的方式把引用关系传递了,如果我们没有改引用关系,而是找到引用的地址,把里面的内容改了,是会对调用方有影响的,因为大家指向的是同一个共享对象。

那么我们改变一下pass方法:

再看一下整个过程中发生了什么:
在这里插入图片描述

这个过程,就好像你复制了一把钥匙给到你的朋友,你的朋友拿到你给他的钥匙之后,找个锁匠把他修改了一下,他手里的那把钥匙变成了开他家锁的钥匙。这时候,他打开自己家,就算是把房子点了,对你手里的钥匙,和你家的房子来说都是没有任何影响的。

所以,Java中的对象传递,如果是修改引用,是不会对原来的对象有任何影响的,但是如果直接修改共享对象的属性的值,是会对原来的对象有影响的。

4、总结

我们知道,编程语言中需要进行方法间的参数传递,这个传递的策略叫做求值策略。

在程序设计中,求值策略有很多种,比较常见的就是值传递和引用传递。还有一种值传递的特例——共享对象传递。

值传递和引用传递最大的区别是传递的过程中有没有复制出一个副本来,如果是传递副本,那就是值传递,否则就是引用传递。

在Java中,其实是通过值传递实现的参数传递,只不过对于Java对象的传递,传递的内容是对象的引用。

我们可以总结说,Java中的求值策略是共享对象传递,这是完全正确的。

但是,为了让大家都能理解你说的,我们说Java中只有值传递,只不过传递的内容是对象的引用。这也是没毛病的。

但是,绝对不能认为Java中有引用传递。


http://chatgpt.dhexx.cn/article/RX1d0bwj.shtml

相关文章

Java复习总结之快速区分值传递和引用传递

引言 为了搞清楚值传递和引用传递的区别,查阅了许多资料,加以自身理解,做出本篇博客用于记录。 概念 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到…

华为应聘进展状态码解析(附加性格测试攻略)

多方查找咨询终于终于看到了自己的状态码,总结一下~ 性格测试攻略: https://blog.csdn.net/guomutian911/article/details/48915301 https://blog.csdn.net/twc829/article/details/51226358 https://blog.csdn.net/twc829/article/details/51226247 第三…

华为OD机试2023 最新最全备考攻略助你轻松上岸

【华为OD机试真题 2022&2023】真题目录 点这里 【华为OD机试真题】信号发射和接收 &试读& 点这里 【华为OD机试真题】租车骑绿道 &试读& 点这里 什么是华为OD 华为OD是Outsourcing Dispacth模式,是华为和外企德科联合招聘的简称。目前华为大多…

idea 怎么导入maven项目

1、打开一个现有的IntelliJ IDEA工程,点击菜单的“File”->“new”->“Module from Existing Sources”。 更详细请点击:http://yayihouse.com/yayishuwu/chapter/1826

IntelliJ IDEA如何导入Gradle项目

https://blog.csdn.net/wangdong5678999/article/details/70255451 IntelliJ IDEA如何导入Gradle项目 栋先生 2017-04-20 10:14:03 95942 收藏 分类专栏: 其他 文章标签: idea intellij idea gradle 版权 最近学习Gradle,本文来重点介绍…

杂记——16.idea中导入maven项目

这篇文章我们来讲一下如何从Gitee上拉取项目,并将该项目导入到idea中 目录 1.拉取项目 2.idea导入项目 3.更改相关的配置 3.1更改maven仓库 3.2更改数据库的连接池 1.拉取项目 第一步:找到相关的项目地址 如图所示,在Gitee上找到相关的…

idea项目导入eclipse中步骤

1、打开eclipse,右键import 找到需要导入的项目 2、重新配置tomcat,已经配置好了建议移除后重新添加, window-preference 3、项目上右键-debug AS-发现没有 debug on server,这是没有转成web项目 项目右键-properties 配置好后会出…

idea与eclipse项目相互导入方式

目录 idea项目往eclipse中导入 idea项目导出到桌面 idea项目导入到工程中 idea项目迁徙到eclipse 第一种导入方式: 第二种导入方式: 第三种导入方式: eclipse项目往idea中导入 idea项目往eclipse中导入 idea项目导出到桌面 直…

idea中导入maven项目并运行

当我们从网上下载人家的maven项目该怎样导入并运行呢,请看如下步骤。 File->New->Project from Existing Source 选择maven项目下的pom.xml文件 File -> Project Structure 填写编译输出路径 6. 如果右边的某些项是红色的,点击右边的maven进行…

IDEA中导入Maven工程或项目

IDEA中导入Maven工程或项目 本文简单讲述了IDEA中导入Maven工程或项目。为了减轻读者压力笔者将 IDEA 相关应用技巧分解成了多篇文章置于主页 IDEA 专栏,若本文没有帮助到您,请去主页 IDEA 专栏检索吧 😏。 文章目录 IDEA中导入Maven工程或项…

使用IDEA导入SpringBoot项目

有时候会拿到别人现成的 springboot 项目,而不是从头自己做一个。 这个时候,就需要用导入的方式来 import 这么一个项目了。 1.IDEA 导入 SpringBoot 项目办法: 1)菜单 -> File -> New -> Project from Existing Sourc…

Intellij IDEA 导入 eclipse web 项目详细操作

Intellij IDEA 导入 eclipse web 项目详细操作 第一步:准备工具我用的是 IntelliJ IDEA 2017.1(64) 这个版本的,在eclipse中找到我之前写skye_cnmy(非Maven),skye_client(Maven)的项目导入。 第二步:在Intellij IDEA File–>New–>Pr…

IDEA导入本地项目

1.文件-New—-Model from Existing Sources 2.选中需要导入的项目 3、选择maven文件选项,从外部模型导入模块。 Idea本地项目部署路径 IDEA不会把你的项目部署到你的Tomcat安装目录,它会在操作系统盘的用户目录下新建一个目录,这个目录一般是…

idea如何import_导入项目

今天"炸药"问我idea如何导入项目: 先close project 再到开始界面import,然后一直next就可以了。 具体操作和注意事项 特别注意: >>> 开始导入项目前,注意,删掉别人电脑的idea配置和class&#xf…

Idea导入项目详解

1.点击Import Project选择项目所在目录 2.Import Project选项区别: 1)如果选择Create project from existing sources选项, 则你只能导入使用idea创建的项目源码 2)如果选择Import project from external model,则你可以导入Eclip…

IDEA导入项目后如何运行

IDEA导入项目后如何运行 过程 开头导入简单就是 import 然后选择文件夹 导入之后对Tomcat的配置,注意正文来了!小菜鸟看图: 上图完成之后,再点“”——tomcat——local—— 下面配Artifact 和其他 ( jar包&#x…

IDEA导入项目

IDEA导入项目 1.先将其解压 2.打开IDEA 选择File–>Open 3.找到刚才解压的文件夹下的文件 选中后点击OK 4.窗口的选择 这里用New Window(新窗口) 5.展开项目 点击Project 6.跟新依赖 点击pom.xml文件 点击一下更新依赖 7.代码测试 打开main\java\com\Demo1和test\jav…

如何在IntelliJ IDEA 中导入别人写好的项目

首先要查看要导入项目的位置在哪(也就是查看文件的属性),记住文件所在的位置(可以先用手机拍下来) 然后打开IntelliJ IDEA在File中找到Open 双击进入 之后进入Open File or Project中,然后一步一步按照自己…

带你认识 M1、UID、CUID、FUID、UFUID

[IC卡类型]带你认识 M1、UID、CUID、FUID、UFUID luck-cheng 2019-02-26 10:15:59 59848 收藏 30 分类专栏: 冷知识 文章标签: ICIC卡m1uidcuid 普通IC卡,0扇区不可以修改,其他扇区可反复擦写,我们使用的电梯卡、门…

RFID第一期——各种IC卡ID卡详解

博客地址:https://lmark.cc/ 起因 放假闲来无事,在B站冲浪,看到有人在讨论IC卡,我在这方面刚好还是有这么一点了解,就拿MF1卡给别人举了个例子,然后MF1卡就被开除出IC卡籍了。 有点气,但是仔细…