java是值传递还是引用传递

2023-11-07

1.前言

java是值传递;值传递是指在调用方法时将实际参数拷贝一份传递到方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数;当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;当传的是引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,因此可以修改原变量中的值。

2.java是值传递还是引用传递

Java是值传递。
当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;当传的是引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,因此可以修改原变量中的值;当传的是String类型时,虽然拷贝的也是引用地址,指向的是同一个数据,但是String的值不能被修改,因此无法修改原变量中的值。

首先来解释一下什么是引用传递,什么是值传递。

引用传递(pass by reference)是指在调用方法时将实际参数的地址直接传递到方法中,那么在方法中对参数所进行的修改,将影响到实际参数。

值传递(pass by value)是指在调用方法时将实际参数拷贝一份传递到方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数。

那在Java中到底是引用传递还是值传递呢?其实这个问题也一直是争论不断,而且官方也没给个确切答案。但是就我个人理解,Java是值转递。

我们先来看一个简单的例子:
在这里插入图片描述
在test()方法中定义了一个基本类型的变量a,然后调用change()方法试图改变这个变量,最后输出的还是原来的值。

首先我们要清楚,一个方法中的局部变量是存在栈中的,如果是基本类型的变量则直接存的是这个变量的值,如果是引用类型的变量则存的是值的地址,指向堆中具体的值。

上面的例子中,调用change()方法传递的a,其实是a变量的拷贝,不是真正的a,在change()方法中改变的是拷贝,对真正的a是没有影响的。

这么一看,Java确实是值传递,但是我们再看下面这个例子,你就会纠结了
在这里插入图片描述
看,对象里的属性被改变了,不是值传递吗,应该不会改变啊,这时候就有人总结了,当传递值是基本类型时是值传递、当传的是引用类型时是引用传递。真的是这样吗?

分析这个问题,我们需要知道变量在jvm中是怎么存储的。

首先看基本类型,这个很简单,变量在栈中直接存的是值,传到change()方法的是这个变量的拷贝,因此对拷贝的变量修改不会影响原变量的值。

接着看引用类型,变量在栈中存储的是引用地址,这个地址指向堆中具体的值,如下图:
在这里插入图片描述
当调用change()方法传入变量时,也是拷贝变量,但是这里的拷贝只是栈中的引用地址,并不会拷贝堆中的数据,因此会变成下图这样:

在这里插入图片描述
虽然变量是拷贝,但是指向的地址是同一个,因此对变量中的数据修改时,还是会影响到原来真实的变量,但是,如果我们修改的是变量在栈中的地址,则不会影响原变量,例如下面这段代码:
在这里插入图片描述
这种是修改变量在栈中的地址,则不会影响原变量。

说到这里,大家差不多懂了,但是回头看最开始的那个问题,传入String类型的变量,String是引用类型,按道理,原变量是会被改变的呀,结果怎么是不变呢?

String变量比较特殊,我们看String的源码可以知道,String的值是通过内部的char[]数组来维护的,但是这个数据定义的是final类型的,因此,String的值是不可变的。我们平时修改String的值,其实是重新new了一个String对象,例如下面这段代码:
在这里插入图片描述
这段代码里,其实a变量并没有被修改成world,只是重新new了一个String对象,这个对象的值是world,并把这个对象的引用地址赋给了a,原来的hello还是在堆中,只是这个值没有被引用,过段时间会被gc垃圾回收。

String变量传值在内存中的变化如下图:
在这里插入图片描述
在这里插入图片描述
String拷贝的是变量地址,但是它改变不了原String的值,因为String是不可变的,所以在change()方法中是重新new了一个String对象,改变的是新对象的值,原变量是没有影响的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java是值传递还是引用传递 的相关文章

  • OSGI - 处理捆绑包所需的第 3 方 JAR

    我刚刚开始 OSGI 开发 正在努力了解如何最好地处理依赖的 JAR 也就是说 如果我要创建一个捆绑包 我很可能需要使用一些第 3 方 JAR 当我创建要部署到 OSGI 的捆绑包 JAR 时 显然不包含这些第 3 方 JAR 因此该捆绑包
  • Intellij Idea:导入Gradle项目-尚未定义JAVA_HOME

    Intellij 理念 14 1 4 Mac OS X Yosemite 10 10 3 及更高版本 从 IDE Import Project gt Chosen directory to import gt Import project
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • java格式化表格输出

    所以我正在尝试格式化我的输出 System out println Menu nItem tItem t tPrice tQuantity for int i 0 i
  • 编译错误:computeFrames 选项不支持 JSR/RET

    当我编译 java 文件时 在 IntelliJ 项目上出现此错误 没有列出特定的源文件 但它失败并出现此错误 删除以下编译器标志可修复该错误 source 1 5 target 1 5 然而 这些需要在那里 因为我们的目标是 Java 5
  • 从 Android Intent 打开图库应用

    我正在寻找一种打开方式Android来自意图的画廊应用程序 我不想返回图片 而是只是打开图库以允许用户使用它 就像他们从启动器中选择它一样 View pictures folders 我尝试执行以下操作 Intent intent new
  • 使用math.random在java中进行猜谜游戏

    您好 我正在尝试使用 Math random 生成 0 到 100 之间的随机数 然后要求用户输入 0 到 100 之间的数字 或 1 退出 如果数字超出范围 且不是 1 请要求用户输入新数字 如果用户没有正确猜出数字 则告诉用户随机数是否
  • 如何一次又一次地使用同一个迭代器?

    给出下一个代码 这是某个大型方法的一部分 ArrayList
  • 如何在另一个 Gui 中启动 JADE Gui?

    如何在另一个 Gui 中启动 JADE Gui 假设我的 Gui 上有一个按钮 点击该按钮后 JADE Gui 将启动 这可能吗 如果是 怎么办 提前致谢 Regards 我假设 JADE Gui 你指的是 JADERMA http jad
  • 使用 Android 将文本文件上传到 Google Drive

    编辑 我已将文本设置为字符串 如下所示 字符串文本 你好 我想将其转换为纯文本文件 然后上传到 Google 云端硬盘文件夹 我已经尝试过下面的代码 但它不完整 所以我无法说出出现了什么错误 我正在使用 Google Drive 快速启动
  • 构造函数中的同步块

    我有一个带有静态变量的类 如下所示 private static Object sMyStaticVar 如果我想在构造函数中为这个 var 赋值 我有这样的代码 if sMyStaticVar null sMyStaticVar new
  • 源单元“_BuildScript_”中“语义分析”阶段出现异常

    评估根项目 android 时出现问题 配置项目 app 时出现问题 无法打开构建文件 C Users InFED Laptop Documents GitHub sustain and save android app build gra
  • while 循环无法访问代码

    当我编译这段代码时 public static void main String args int x 0 while false System out println hello 它显示编译时错误无法访问代码 但是当我将这段代码修改为 p
  • 如何解除阻塞在 ServerSocket.accept() 上的线程?

    我有一个带有以下代码的服务器线程 public void run try ServerSocket server EneaLog printLog Server is running server new ServerSocket this
  • RequestDispatcher.forward 到媒体文件?

    我最近有一个需要解决的问题 https stackoverflow com questions 19385223 how to transparently stream a file to the browser并找到了一个解决方案 但如果
  • 当基类和派生类都具有同名变量时会发生什么

    考虑int a这些类中的变量 class Foo public int a 3 public void addFive a 5 System out print f class Bar extends Foo public int a 8
  • lwjgl 3 , glUniformMatrix4 导致 jre 崩溃

    我正在使用 lwjgl 3 并学习现代 opengl 3 我想将统一矩阵发送到顶点着色器 以便我可以应用转换 我尝试过 但程序因此错误而崩溃 A fatal error has been detected by the Java Runti
  • Java 中的 ConcurrentHashMap 和 Hashtable [重复]

    这个问题在这里已经有答案了 Java 中的 ConcurrentHashMap 和 Hashtable 有什么区别 哪个对于线程应用程序更有效 ConcurrentHashMap 和 Hashtable 锁定机制 Hashtable属于Co
  • TextView 用字母打乱了我的话

    我的要求 创建 传入气泡 其宽度按内容排列 最大宽度为 90 我有这个标记
  • Java无限信号量

    想知道如何not使用信号量限制连接 或任何东西 所以你可能会想 这听起来很愚蠢 但是 它稍微简化了我的代码 因为它让我可以统一处理有限和无限的情况 请注意 我并不是在寻找有关如何编写类似内容的建议 if limited semaphore

随机推荐

  • 加密货币市值、股市市值、房地产价值

    加密货币市值 股市市值 房地产价值 全球加密货币市值共0 85万亿美元 统计时间2022年12月6日 比特币 时间2022年12月6日价值0 33万亿美元 其他 时间2022年12月6日价值0 52万亿美元 全球流通货币价值共8万亿美元 统
  • @【 ENVI】“应用程序无法正常启动0x0000007b”问题

    ENVI 应用程序无法正常启动0x0000007b 问题 ENVI5 3 百度网盘 链接 https pan baidu com s 1P1nI9fKEGeNbSsMt9D3mMA 提取码 zely 记得安装目录里面不能有中文 idlrt
  • 无线鼠标计算机不识别,教你笔记本电脑检测不到无线鼠标如何解决

    无线鼠标由于没有线的牵绊 受到很多网友的喜爱 特别是笔记本电脑用户 不过最近有网友说自己的笔记本电脑检测不到无线鼠标怎么办 无线鼠标失灵了 其实这个是很常见的问题 造成的原因也比较多样 下面小编就给大家分享下笔记本电脑识别不了无线鼠标的解决
  • 从零开始学nginx

    1 nginx简介 nginx 发音同engine x 是一款轻量级的Web服务器 反向代理服务器及电子邮件 IMAP POP3 代理服务器 并在一个BSD like协议下发行 nginx由俄罗斯的程序设计师Igor Sysoev所开发 最
  • Ubuntu下如何用命令行运行deb安装包

    如果ubuntu要安装新软件 已有deb安装包 例如 iptux deb 但是无法登录到桌面环境 那该怎么安装 答案是 使用dpkg命令 dpkg命令常用格式如下 sudo dpkg I iptux deb 查看iptux deb软件包的详
  • 有序充电运营管理平台是基于物联网和大数据技术的充电设施管理系统-安科瑞黄安南

    随着我国能源战略发展以及低碳行动的实施 电动汽车已逐步广泛应用 而电动汽车的应用非常符合当今社会对环保意识的要求 以及有效节省化石燃料的消耗 由于其没有污染排放的优点以及政府部门的关注 电动汽车将成为以后出行的重要交通工具 由于大批的电车作
  • openssl AES加密、解密示例代码

    openssl AES加密 解密 关于加密解密后长度的说明 AES 高级加密标准 是一种对称加密算法 它使用相同的密钥进行加密和解密操作 无论是加密还是解密 输入和输出的字节数保持一致 AES算法操作的数据以字节为单位 输入数据被分成16字
  • TensorFlow是什么

    TensorFlow是一个开源的深度学习框架 由Google开发 用于构建和训练神经网络 它提供了一种简单而灵活的方法来构建各种类型的机器学习模型 包括卷积神经网络 循环神经网络 深度神经网络等 TensorFlow使用图和张量的概念来描述
  • Mysql免安装版的root密码是多少

    免安装版的Mysql在初始化后root是没有密码的 1 下载免安装版Mysql 下载链接 MySQL Download MySQL Community Server 下载后解压 里面的目录是这样的 2 添加配置文件和系统环境 在系统变量中添
  • redis bitmap实现签到(包含工具类)

    很多应用比如签到送积分 签到领取奖励 签到 1 天送 10 积分 连续签到 2 天送 20 积分 3 天送 30 积分 4 天以上均送 50 积分等 如果连续签到中断 则重置计数 每月初重置计数 显示用户某个月的签到次数 在日历控件上展示用
  • Spring 基础--第一个spring项目及IOC

    一 第一个spring项目 1 导入Jar包
  • 准备写本书

    立个flag 写本书 关于数字IC物理设计 为了避免半途而废 本人在此立下flag 今天起 两年为期 写一本关于数字IC物理设计的书 初步想法 利用公众号专辑功能 先从小章节写起 然后汇聚成册 请大家监督 本来年初就想写 但是迟迟没下定决心
  • 服务器被爬虫恶意攻击怎么办?

    在有预算的情况可以采购第三方服务防火墙 没钱就使用开源的WAF进行防护 WAF防火墙的基本防护原理 WAF Web 应用防火墙 可以使用多种技术来防止恶意爬虫攻击 例如 1 黑名单 WAF 可以使用黑名单技术来过滤恶意爬虫的请求 黑名单中包
  • 【机器学习】TF-IDF以及TfidfVectorizer

    TF IDF定义 TF IDF 全称为 词频一逆文档频率 TF 某一给定词语在该文档中出现的频率 T F w 词语 w
  • common-lang包中一些工具类的使用说明

    一 common lang包常用的类有 1 StringUtils类 该类主要提供对字符串的操作 对null是安全的 主要提供了字符串查找 替换 分割 去空白 去掉非法字符等等操作 2 ObjectUtils类 主要是对null进行安全处理
  • vs网站 服务器变量,了解下变量赋值 (值 vs 引用)

    理解 JavaScript 如何给变量赋值可以帮助我们减少一些不必要的 bug 如果你不理解这一点 可能很容易地编写被无意中更改值的代码 JavaScript 总是按照值来给变量赋值 这一部分非常重要 当指定的值是 JavaScript 的
  • Qt的信号和槽是如何工作的

    用Qt做过开发的朋友 不知道是否曾为下面这些问题疑惑过 我们知道Qt是基于C 的 Qt写的代码最终还是要由C 编译器来编译 但是我们的Qt代码中有很多C 里没有的关键字 比如slots signals Q OBJECT等 为什么C 编译器会
  • mpvue页面卸载数据不清空

    mpvue有个坑页面卸载了 在小程序层面上是销毁了 但是vue层面页面的实例还在 为了实现再次进入清除数据的效果 可以试一下这个折中的办法 在onload里面清除一下实例中的数据 onLoad e Object assign this th
  • Leaflet使用wfs的示例

    Leaflet是一个开源的Web地图库 可以用来在网站上显示地图 可以使用Leaflet的功能扩展 Leaflet WFS 来在Leaflet地图中使用WFS Web Feature Service 功能 以下是使用Leaflet和Leaf
  • java是值传递还是引用传递

    文章目录 1 前言 2 java是值传递还是引用传递 1 前言 java是值传递 值传递是指在调用方法时将实际参数拷贝一份传递到方法中 这样在方法中如果对参数进行修改 将不会影响到实际参数 当传的是基本类型时 传的是值的拷贝 对拷贝变量的修