java:值传递,引用传递,为什么JAVA只有值传递(含图解)

Java参数传递机制:值传递与引用传递的常见误解 本文详细解析了Java的参数传递机制,澄清了常见的误解。Java严格采用值传递,对基本类型传递值副本,对引用类型传递对象引用的副本。通过代码示例和内存模型分析,文章展示了基本类型修改不影响原值,而引用类型修改会影响原对象内容但不改变原始引用。文章还对比了不同语言的参数传递方式,分析了字符串和集合类等复杂场景,强调不可变对象的特殊行为。最终结论是:Java始终是值传递,理解这一机制对避免程序错误至关重要。 阅读详情

前言
JAVA对于对象类型的参数传递,主流解释是:“JAVA传递对象类型的时候,传递的不是对象本身,而是对象的地址”。这句话容易让人误解为这是引用传递,确实这种传递方式表现得类似于引用传递,但实际上JAVA仍然是值传递。

0.太长不看

核心区别:
值传递:传递引用的副本(将对象的地址复制到新的一块内存中传递)
引用传递:传递引用本身(直接传递对象的地址)


1.图片解释

看下面的例子:
我有一个类Food,三个对象Food 鸡蛋、Food 苹果、Food 西瓜,一个引用Food 引用,一个方法 void eat(Food food)
        对于对象的“引用传递”

        对于对象的“值传递”

接下来,我想在eat中修改原来的“Food 引用”,让其引用苹果,那么就发生区别了。比如要将“Food 引用”改成引用“Food 苹果”,那么就回出现下面的区别:
        对于对象的“引用传递”
 

        对于对象的“值传递”


看到区别了吗,引用传递可以在eat()内部修改“Food 引用”本身,让其转而引用“Food 苹果”;值传递,在eat()内部只能修改“Food 引用的副本”,不能修改“Food 引用”本身。

2.代码示例:
 

class Food {
    String name;
    
    Food(String name) {
        this.name = name;
    }
    
    void eat() {
        System.out.println("Eating " + name);
    }
}

public class FoodExample {
    public static void main(String[] args) {
        Food egg = new Food("Egg");
        Food apple = new Food("Apple");
        
        System.out.println("=== 初始状态 ===");
        System.out.println("main方法中: egg指向=" + egg.name);
        System.out.println("main方法中: apple指向=" + apple.name);
        
        System.out.println("\n=== 调用eat方法,传入egg ===");
        eat(egg, apple);
        
        System.out.println("\n=== eat方法调用后 ===");
        System.out.println("main方法中: egg指向=" + egg.name); // 仍然是Egg!
        System.out.println("main方法中: apple指向=" + apple.name);
    }
    
    // 尝试在方法中修改引用指向
    static void eat(Food food, Food newFood) {
        System.out.println("eat方法开始时: food指向=" + food.name);
        
        // 尝试修改引用指向apple
        food = newFood;  // 这里只修改了副本引用!
        
        System.out.println("eat方法修改后: food指向=" + food.name);
        food.eat();  // 这里吃的是Apple,但只在方法内有效
    }
}

输出结果:
 

=== 初始状态 ===
main方法中: egg指向=Egg
main方法中: apple指向=Apple
=== 调用eat方法,传入egg ===
eat方法开始时: food指向=Egg
eat方法修改后: food指向=Apple Eating Apple
=== eat方法调用后 ===
main方法中: egg指向=Egg
main方法中: apple指向=Apple

3. 内存模型图解

调用 eat(egg, apple) 时的内存状态:

text

栈内存:
main方法栈帧:
egg   ─────→ [Food对象] name="Egg"
apple ─────→ [Food对象] name="Apple"

eat方法栈帧:
food (egg的副本) ───→ [Food对象] name="Egg"  
newFood (apple的副本) → [Food对象] name="Apple"

执行 food = newFood 后:

text

main方法栈帧:                    (未变化)
egg   ─────→ [Food对象] name="Egg"
apple ─────→ [Food对象] name="Apple"

eat方法栈帧:
food (现在指向apple) ──────────→ [Food对象] name="Apple"  
newFood ──────────────────────┘

4. 关键区别总结

特征Java实际(值传递引用)真正的引用传递
传递内容引用的副本引用本身
修改引用指向只影响方法内的副本影响原始引用
修改对象内容会影响原始对象会影响原始对象
比喻给钥匙复印件给钥匙原件
CondaHTTPError: HTTP 404 NOT FOUND for url 用conda创建新环境时出现问题了。 阅读详情

相关推荐

固定翼飞行器建模(二)——MATLAB/Simulink建模、配平及线性化

MATLAB/Simulink固定翼建模、配平及线性化。

2302_80148937的博客 1万+

Java参数传递:值传递还是引用传递?看完这篇别再被面试官问倒了!

误区1:“Java对象是引用传递,所以方法内能改原引用。反驳:若真是引用传递,方法中的应该能改变外部的user变量,但实测不行!误区2:“基本类型是值传递,对象类型是引用传递。反驳:对象传递的仍是引用的值(地址副本),而非引用本身,因此仍是值传递。一句话结论:Java只有值传递!对象类型传递的是引用地址的副本。面试技巧先明确值传递和引用传递的定义。通过“能否修改原引用指向”来反驳“对象是引用传递”的错误观点。画内存图解释,瞬间征服面试官!

qq_62775328的博客 730

直流电机双闭环调速系统MATLAB仿真

Chopper-Fed DC Motor Drive This example shows a Chopper-Fed DC Motor Drive. Description The DC motor is fed by the DC source through a chopper which consists of GTO thyristor and free-wheeling diode ...

飞行动力的博客 2万+

Java 传递机制:值传递还是引用传递?(详细图文版)

前言 明白Java中的传递机制,有助于帮助我们更好的理解Java在内存中的地址指向。这篇文章我会通过尽可能简单的讲解,让大家更好的理解。 1. 传递类型 首先,我们需要知道,传递类型指的是调用函数时传入的参数传递的方式。传递类型包括两种:值传递和引用传递 值传递:我们传入的实参拷贝一份传给函数的形参,在函数中操作形参不改变实参的值 引用传递:我们传入的实参实际上传入的是其在内存中的地址指向,在函...

Joker小兮的博客 594

从共现矩阵到共现图一步到位——详解版

1.共现矩阵 判断大量不同文本之间,相邻词的联系,两词在所有文本中相邻的次数在矩阵中用数值表示。(参考此) 例子如下: 1.1 文本 • I like deep learning. • I like NLP. • I enjoy flying. 1.2 共现矩阵 2.共现图 2.1 数据预处理(节点和边) 获取文件node.csv和edge.csv。代码详见github仓库 2.2 共现图的制作 2.2.1 gephi的安装(参考此) (1)先下载gephi (2) 再配置java环境(下载java1.8

微乐的博客 4401

1.2 重叠因子:双重指数移动平均(Double Exponential Moving Average, DEMA)概念与Python实战

双重指数移动平均(Double Exponential Moving Average, DEMA)是一种改进的移动平均线指标,由Patrick Mulloy在1994年开发。相比传统的指数移动平均线(EMA),DEMA通过减少滞后性来提供更快的市场反应。它通过两次计算EMA并进行特殊组合来实现这一目标,可以在保持平滑性的同时减少滞后。

Kewin的博客 2166

java中什么是值传递

我们首先用一个例子引出这个问题(后面会放出全部代码) 如下图代码,输出后a和b的值,以及张三李四会交换吗 我们直接给出结果: 结果一定是不会交换的 那么为什么他不会交换呢?我给大家画一下这段程序执行时堆栈的解析图 首先Main方法入栈,然后实例化a,b,我们不妨设10所在地址为1001,b所在地址为1002,然后让ab分别指向他们,然后change(a,b)方法入栈实例化abt 然后t =a ,a=b,b=t 也就是让t指向a(1001),a去指向b(100...

peinanwei__的博客 4346

企业微信/飞书/钉钉扫码连WiFi保姆级教程(附访客授权技巧)

本文提供了一份企业微信、飞书、钉钉扫码连接WiFi的实战部署教程。通过集成标准Radius协议与OAuth 2.0,企业可实现基于身份的无密码网络认证,并详细介绍了访客授权、权限分级等精细化管理技巧,有效提升无线网络的安全性与员工体验。

t4y5u6i7o的博客 1194

Java的值传递

 对值传递、引用传递有些疑问,综合其他人的解释,加上自己的理解,在这里分享一下,如有不当之处,恳请指出。1、概念  值传递、引用传递,是计算机领域的专有名词。  值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递的内容的类型(内容指:是值类型还是引用类型,是值还是指针)。(参考:链接:https://www....

da_zhan_zhan的博客 532

混合动作空间在强化学习中的创新应用:PDQN与MPDQN算法解析

本文深入解析了强化学习中处理混合动作空间的PDQN与MPDQN算法。针对既有离散选择又有连续调节的复杂决策场景,PDQN通过参数化深度Q网络,巧妙结合DQN与DDPG进行交替优化;MPDQN则进一步改进,为每个离散动作提供专属参数评估以减少干扰。文章通过游戏、自动驾驶等实例阐述了其应用价值与面临的挑战。

efc123456的博客 861

多agv系统调度的MATLAB仿真

从起点出发,到货物点领取货物最后到卸货点,以完成任务总时间最短为目标进行单目标优化,约束条件为,任务不冲突,路径不冲突,要能实现路径规避 ,4-6台agv一起工作。左右货架间隔可通过1个agv,上下货架间隔可通过两个agv,通道为双向行驶通道。一台agv只能带一个货物,优化目标为完成任务总的时间最短,agv的速度是匀速,转弯也不会减速,取货物时间为固定值。上面的图里面货物看为正方形跟agv一样的长度大小,agv试做是跟货物一样大小的正方形agv的速度是每秒1个车身。多台agv一起完成...

FPGA/MATLAB学习教程/源码/项目合作开发 7563

java 值传递简单透彻理解

值传递 以及 引用传递简单 介绍。 值传递         指的是在方法调用时,传递的参数是按值的拷贝传递 (传递前 和传递后 对象的引用不变  java 中基本数据                     类型以及对应的 包装类 经过方法传递是 值不会改变) 引用传递     指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存

在鬼混的博客 667

FANUC机器人S523 新款PN板卡与西门子PLC通信配置介绍

FANUC机器人S523 新款PN板卡与西门子PLC通信配置介绍

Robot_PLC_HMI_Automation 347

【JAVA】 什么是值传递和引用传递?

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量. 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 一般认为,java内的基础类型数据传递都是值传递. java中实例对象的传递是引用传递 首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上...

疯 4万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java参数传递终极揭秘:值传递还是引用传递?看完这篇彻底懂了!

Java参数传递遵循值传递原则,对基本类型传递值的副本,对引用类型传递对象引用地址的副本。方法内可通过副本修改对象内容(如属性值),但无法改变原始引用的指向(如new操作或null赋值)。常见误解如String的不可变性、数组/集合的修改等,均源于对"引用副本传递"的误读。关键结论: 对象内容可修改(通过副本操作原对象) 引用指向不可变(副本重定向不影响原引用) 设计初衷:保障安全性(防意外篡改)与一致性(统一传递规则)。面试回答需区分基本类型与引用类型的副本传递本质。

yiridancan的博客 3489

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

为什么Java中只有值传递?

值传递:方法接收的是实参值的副本。对形参的修改不会影响实参。引用传递:方法接收的是实参的地址本身(可以理解为实参变量在内存中的门牌号)。对形参的修改会直接影响实参,因为形参和实参指向的是同一个地址。Java 中的“引用”更像是一个“地址值”或“指针值”,它本身也是一个值。这是产生混淆的地方。System.out.println("调用前 person.name = " + person.getName());// 输出 Alice。

学亮编程手记 1106

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

什么是值传递和引用传递?之间的区别

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34008784的博客 5787

java中的值传递和引用传递

值传递(Pass By Value或者Call By Value)是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。一般java中的基础类型数据传递都是值传递。 引用传递(Pass By Reference或者Call By Reference)一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。一般java中实例(包装)对象的传递是引用传递。 一、基本类型和引用类型在内存中的不同之处 int num = 10; String str = "hello"

m0_51660523的博客 4679

为什么Java只有值传递

我们先看一下值传递和引用传递的概念和区别 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 引用传递:是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 值传递和引用传递的区别: 值传递会创建副本,引用传递不创建副本 值传递的函数中无法改变原始对象,引用传递中函数 可以改变原始对象 ...

sinat_41920065的博客 1065

integer是值传递还是引用传递_值传递与引用传递

值传递:指的是在方法调用时,传递的是参数是按值的拷贝传递。特点:传递的是值的拷贝,也就是传递后就互不相关了。引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的是引用的地址,也就是变量所对应的内存空间的地址。特点:传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。对于这两种传参方式,假如你写过一些java程序后,你就会发现这不就是看传的参数是基本类型...

weixin_39588911的博客 2271

为什么 java 参数是 值传递,不是引用传递

Java严格采用"按值传递"机制,无论传递基本类型还是对象引用。对于基本类型,传递的是值的副本;对于对象引用,传递的是引用的副本而非对象本身。这意味着方法内可以修改引用指向的对象内容,但无法通过赋值改变原始变量的引用指向。这种设计与真正的"按引用传递"(如C++的&操作符)有本质区别,后者允许直接修改原始变量的引用指向。因此,Java的参数传递应准确描述为"传递值的副本",对于对象则是"传递引用的副本"。

zfj321的博客 878

值传递和引用传递(地址传递)的区别

值传递和引用传递(地址传递)的区别 也许大家对于被值传递和引用传递(看了些别人的博客也有人说只有值传递)弄得傻傻分不清楚,我个人之前也是这样过来的,自己也思考了一番,后来才弄清楚了,结合大多数人的想法总结: 八大基本数据类型:(byte, boolean, char, short, int, long, float, double) 值传递 引用类型:(数组, 类, 接口) 地址传递 我觉得大家也...

棉花糖的博客 6875

小白都能看懂的引用传递小案例

前言 今天逛论坛,遇到一个新手问引用传递的问题,特此记录。 问题是什么 我们先看一下遇到的问题是什么 User类只有一个属性 public static void main(String[] args) { User user1 = new User(); getUser(user1); System.out.println(use...

我爱吃土豆 6348

通过底层原理理解Java是值传递还是引用传递?

快手一面,Java基础考察,值传递 or 引用传递?

无休居士的博客 1014

c语言值传递和引用传递的区别_Java是值传递还是引用传递

Java 到底是值传递还是引用传递?先说结论,Java 都是值传递,不存在引用传递。数据类型首先从 Java 数据类型入手,Java 的数据类型分为基础类型和引用类型。基础类型声明时在栈空间开辟内存,数值直接存储在栈空间。引用类型声明时在栈上开辟内存,用于存储对象的地址,而对象的具体信息存储在堆空间。int num = 10;String str = "java";如图,num 是基本类...

weixin_39586825的博客 630

java中永远都是值传递,没有引用传递对吗?

????1、基本数据类型参数传递2、引用数据类型参数传递3、"传引用"一定能成功修改值吗? 错误理解①:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误理解②:Java是引用传递。 错误理解③:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。 基本数据类型: byte char short int long float double boolean 引用数据类型: 接口类型(List) 、类类型(ArrayList) 、数组(int

cheng 462
上一篇: java:理解java bean 和 spring bean
下一篇: java:POJO、BO、VO、PO、DO、DTO分别代表什么?怎么用?
talenteddriver
博客等级 码龄5年 12粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值