秒懂Java为什么只有值传递

news/2025/3/12 10:00:38/文章来源:https://www.cnblogs.com/dennyLee2025/p/18571041

在Java语言中,数据类型分为基本数据类型和引用数据类型。

基本数据类型(如intdoublechar等)的值直接保存在栈上。这些类型的变量在栈内存中有固定的大小,并且值是直接存储在这些变量中的,数据的传递为值传递,这个好理解。以下以引用数据类型来讲解。

引用和实例化对象

比如new一个对象的代码:等号左边的person为引用;等号的右边new Person()为实例化对象。

Person person = new Person();
引用 = 实例化对象

引用实例化对象在内存中,分别保存在中。引用会保存着实例化对象的地址,从而可以通过引用来获取到具体的实例化对象保存在哪里。

关系如图:

在这里插入图片描述

值传递和引用传递

顾名思义,值传递是把“值”传递到方法中,而引用传递是把“引用”传递到方法中。

在Java 的参数传递方式中,只有值传递。对于引用对象也是值传递,而这个引用的值(即堆地址或句柄)被拷贝传递到方法中。

文字太抽象了,看图和代码:

在这里插入图片描述
在这里插入图片描述

对比两者

值传递

源引用地址:0x0a --> 对象地址:0x10
传递时:新引用地址:0x0b --> 对象地址:0x10

引用传递

源引用地址:0x0a --> 对象地址:0x10
传递时:方法中仍是引用地址:0x0a --> 对象地址:0x10

值传递:是复制一份“引用”传给方法的形参,personperson2 是两个不同的栈内存地址(如 0x0a0x0b

引用传递:是将实参的引用直接传给方法的形参,personperson2 实际共享了相同的栈内存地址(如 0x0a

两者有着本质的区别!对比两者的行为和带来的影响。

对比示意图

行为 值传递(Java 的实际行为) 引用传递(假设机制)
方法参数接收到的值 引用地址的副本(如 0x0b 原始引用地址本身(如 0x0a
引用的改变影响范围 改变方法内的引用指向,不影响原始引用 改变引用指向会影响原始引用
对象属性的修改 通过引用修改对象属性,会影响原始对象 通过引用修改对象属性,会影响原始对象

代码验证

测试代码:测试引用的改变影响范围和对象属性的修改

public class ValuePassDemo {public static void main(String[] args) {Person person = new Person();person.setAge(18);person.setName("Denny");// 初始值System.out.println("地址:"+ Integer.toHexString(person.hashCode()) + ">>>" + person);modifyReference(person);// 是否会被上一个方法修改值System.out.println("地址:"+ Integer.toHexString(person.hashCode()) + ">>>" + person);modifyReference2(person);// 是否会被上一个方法修改值System.out.println("地址:"+ Integer.toHexString(person.hashCode()) + ">>>" + person);}/*** 形参和实参引用指向的实例化对象是同一个* 实例化对象的值被任意一边修改时,都会改变*/public static void modifyReference(Person person2) {person2.setAge(28);person2.setName("Jack");System.out.println("地址:"+ Integer.toHexString(person2.hashCode()) + ">>>" + person2);}/*** 如果是引用传递,*   那实参引用 person 等于形参引用 person2,*   那么引用 person2 的指向被改变的话,形参引用 person也会指向新的实例化对象* 如果不成立,那就是值传递,引用person2 只是引用person的拷贝,而非本身给了它*/public static void modifyReference2(Person person2) {person2 = new Person();person2.setAge(20);person2.setName("apple");System.out.println("地址:"+ Integer.toHexString(person2.hashCode()) + ">>>" + person2);}
}

测试结果:

在这里插入图片描述

方法内部修改引用的指向

调用modifyReference2方法,会给形参变量赋一个新的实例化对象的情况,

如果是值传递,形参和实参分别指向不同的实例化对象,如图:

在这里插入图片描述

如果是引用传递,形参和实参都指向相同的实例化对象,而原来的实例化对象就没有引用指向。

如图:

在这里插入图片描述

原来的实例化对象没有引用指向,会导致内存泄漏,用C++的语言描述:按引用传递时,并且在方法内修改引用指向新new的对象时,需要手动释放内存。

  • void myFunction(Person* obj)按值传递
  • void myFunction(Person*& obj)引用传递
void myFunctionWithReference(Person*& obj) {delete obj;  // 先释放原对象的内存obj = new Person(20);  // 重新分配新的对象,并让 obj 指向它
}

为什么Java只有值传递

个人觉得Java 选择只有值传递的参数传递机制(pass-by-value)目的应该包含:内存安全性、简化内存管理、保持语言行为一致性和语言简单易用。

这也是Java语言的优点,弱化对内存操作的概念,让这门语言更加简洁易用;同时这也是Java语言的缺点,降低了灵活性,无法直接通过方法修改引用变量的指向。

在这里插入图片描述

超实用的SpringAOP实战之日志记录

软考中级--软件设计师毫无保留的备考分享

单例模式及其思想

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

什么是设计模式?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/841853.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

几何校准 和 ros环境下标定Balser相机

几何校准 基本概念 内参数内参数是相机内部的参数,与相机的位置无关,由镜头和感光元器件的特性决定。 包括:主距,主点,畸变参数畸变参数 径向畸变:正和负径向畸变[@] 正径向畸变 (桶形畸变):在这种畸变中,图像中心附近的点会向外移动,图像看起来像是从中心向外膨胀,尤…

datax的安装与使用

1、datax简介概述 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。支持的数据源2、架构 为了解决异构数…

Ollma本地部署Qwen2.5 14B(不使用docker)

部署机器硬件情况: 内存 :32GB 显卡 :3060 为什么不使用docker: 1.网上教程大多以docker为主 2.安装docker的时间太长,在等待的时候顺便尝试一下不用docker的部署 1.安装Ollama 下载地址:https://ollama.com/ 下载好之后默认安装即可。Ollama常用命令 【跟docker差不多,初…

[题解]2024/11/26 模拟赛

校内自命题模拟赛,密码:校OJ地址 http://___.__._.__:____/ 补全pencil 挺板的,点\(u\)的答案是\(dis(1,u)+dis(u,n)\),边\(e=(u,v)\)的答案是\(\min(dis(1,u)+dis(v,n),dis(1,v)+dis(u,n))+w(e)\)。其中\(dis(u,v)\)表示\(u\)到\(v\)的最短路。 从\(1\)和\(n\)各跑一次Dij…

【Autodesk Revit 2025下载与安装】

1、安装包 「Revit 2025」: 链接:https://pan.quark.cn/s/9342ceb1f179 提取码:WmPW 2、安装教程(建议关闭杀毒软件) 1) 双击Setup.exe安装,弹窗安装对话框2) 勾选‘我同意。。’,点击下一步3) 选择软件安装路径,建议C盘之外进行安装,点击安装4) …

CyclicBarrier的介绍

CyclicBarrier的介绍概要CyclicBarrier(循环栅栏/循环屏障)是java.util.concurrent工具类里的一个工具,它是Java提供的一种特定场景下的多线程之间进行交互的使用方法。CyclicBarrier 作用是让一组线程相互等待,当达到一个共同点时,所有之前等待的线程再继续执行,且 Cycl…

Eplan 2024下载与安装

1、安装包EPLAN Electric2024: 链接:https://pan.quark.cn/s/d44ddafa837a 提取码:FpKb 2、安装教程(建议关闭杀毒软件) 1) 解压下载的文件,查看文件目录2) 找到host文件并修改计算机本地host,文件位置(C:\Windows\System32\drivers\etc)3) 拖拽文件…

AI+若依

AI+若依https://www.bilibili.com/video/BV1pf421B71v/?spm_id_from=333.337.search-card.all.click&vd_source=b1acc63fa6d7d73e53111f9e1153f990若依扫盲通义灵码(AI)CRM客户关系管理系统(后台管理系统)选型与搭建:技术选型,环境搭建,框架整合(AI凉凉)设计:基…

ETL数据采集之Sqoop的安装部署及操作

ETL数据采集 数据采集也叫数据集成 ,我们常说的爬虫也是数据采集的一种方式 。 常用的数据采集工具分为两大类:离线数据采集(批量数据采集),实时数据采集(增量数据采集),这次我们分别来学习一下这俩种采集方式的常用工具 离线数据采集 常用工具有Sqoop、DataX、Kettle …

CTF学习(19)MISC(面具下的flag)

1.解压后发现为.jpg格式的文件--->使用010editor打开后搜索flag发现存在两个疑似flag文件的标识 第一处:第二处:2.在kali使用binwalk发现藏有两个文件--->爆破zip文件(无果,可能是伪加密?)分离后的文件:3.检查文件头加密部分(偶数,无加密)--->检查文件尾加密部分 09 …

差旅费报销管理信息系统进度1(2022java期末考试练习)接上题目

目前做了第一个表出差申请的增删改查项目结构mapper中放sql语句 service写函数定义 web写具体servlet操作 前端用html+jsp

2024.11.26总结

DrRatio本文于 github 博客同步更新。 A: 学生大战一个半小时未果,结束前半小时发现是打表找规律。 就是分讨一下,首先大于 \(1\) 的数不能超过两个,若有两个则其中一个必定为 \(2\),然后看一下 \(1\) 的个数是不是 \(3\) 的倍数即可。 B: 拆贡献,分为 \(u\rightarrow l…