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

本文详细解析了Java中对象参数传递的机制,澄清了基本类型传递与引用传递的误区,并通过代码实例展示了Java中对象参数传递的真实过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近和同事讨论算法效率问题无意中涉及到一个问题,java中调用方法的时候是值传递呢?还是引用传递?网上搜索一下相关问题,众说纷纭骂人,有人说值传递,有人说引用传递,还有人说”基础类型是值传递,对象类型是引用传递“。那么我们就用简单客观的代码分析一下可怜

值传递

值传递是指将该值复制一份出来使用,比如a复制一份a1出来,a1做的操作不会影响到a。例子如下:
<span style="white-space:pre">	</span>public static void methodOne(int a) {
		a++;
		System.out.println("methodOne a="+a);
	}
	
	public static void main(String[] args) {
		int a = 100;
		methodOne(a);
		System.out.println("main a="+a);
	}
输出结果为:
methodOne a=101
main a=100
很明显这是值传递。不多解释。主要的问题出现在下面引用传递

引用传递

引用传递是将该值的地址传递给方法,比如取a的地址值b,b指向a,可以通过b找到a并对a进行修改。这时候a的值就会改变。废话不多说,上代码:
<span style="white-space:pre">	</span>public static void methodTwo(List<Integer> a) {
		a.add(101);
	}
	
	public static void main(String[] args) {
		List<Integer> a = new ArrayList<Integer>();
		a.add(100);
		methodTwo(a);
		System.out.println("main a="+a.toString());
	}
运行的结果如下:
main a=[100, 101]
这时候,很多人会说,看,java中的基本类型是值传递,对象类型是引用传递。如果这样认为的话,那就大错特错了。再来看看下面的代码:
<span style="white-space:pre">	</span>public static void methodTwo(List<Integer> a) {
		a = new ArrayList<Integer>();// 就在这加了这一句
		a.add(101);
	}
	
	public static void main(String[] args) {
		List<Integer> a = new ArrayList<Integer>();
		a.add(100);
		methodTwo(a);
		System.out.println("main a="+a.toString());
	}
运行结果如下:
main a=[100]
这时候应该很多人就蒙逼了惊讶,这算闹哪样呀,不是引用传递吗?应该是main a=[101]才对的呀!现在我们静下来分析一下,java中方法之间传递对象参数的内存变化是怎样的?来,我们从代码一句一句分析下来。
<span style="white-space:pre">	</span>List<Integer> a = new ArrayList<Integer>();
这时候内存里边会有这样一个模型(图不是很漂亮,大家将就一下可怜):


当调用methodTwo方法时,模型变如下:
这时候应该就清晰很多了,对象引用a被复制了一份出来使用,methodTwo拿到的是a的复制品。当methodTwo中调用
<span style="white-space:pre">	</span>a = new ArrayList<Integer>();
模型变化如下:

这时候应该都恍然大悟了吧。在new一个新的对象出来之后,methodTwo方法的a指向了新的对象实例,所以怎么改变都不会改变main方法中a的对象。同时也可以证明,java中只有值传递没有引用传递,在传递对象时,是传递对象的引用的副本,不是直接传递对象的引用本体。

总结

java这个特性应该很多人都不太了解,因为这种东西很少人去探究,敲代码敲多了,反反复复都是这样的语句,没有时间去思考也觉得没必要去思考。但一旦出现bug,就会难倒一堆人。一个小问题就会涉及到java底层的原理。

这是我个人第一篇技术博文,希望对你有所帮助奋斗。哈哈,第一篇呢,第一篇呢,得意有点小激动,每周一更,希望能做到。

(唉,这篇文章文字还是很少,因为本人语言功能性短缺偷笑,写的不好请多多指正,程序员看看图应该懂吧大笑
<think>好的,我现在需要仔细理解用户的问题。用户想了解Java中的参数传递机制,特别是判断是值传递还是引用传递。根据用户提供的引用内容,Java的参数传递值传递,不管是基本数据类型还是引用类型。但用户可能对引用类型的值传递机制有疑问,比如为什么修改对象属性会影响原对象。 首先,我应该明确区分基本类型和引用类型在内存中的存储方式。基本类型的变量直接存储值,而引用类型的变量存储的是对象的地址。当传递参数时,无论是基本类型还是引用类型,传递的都是值的拷贝。对于引用类型来说,拷贝的是地址值,因此通过这个地址可以修改原对象的内容,但这并不改变传递机制本身,仍然是值传递。 接下来需要解释为什么修改数组或对象的属性会影响到原数据。例如在引用[1]的示例中,方法内部修改了数组元素,导致原数组变化。这是因为方法内获得了数组地址的拷贝,指向同一个对象,所以修改对象内容会影响原变量。但是,如果尝试在方法内让形参指向新对象(比如arrs = new int[3];),原变量不会改变,因为此时形参的地址拷贝被修改,而实参仍然指向原来的对象。 用户可能存在的误区是认为引用传递意味着直接操作原变量,而实际上Java中没有引用传递,只有值传递。需要举例说明两种不同情况:修改对象属性与重新赋值形参的区别。同时,引用用户提供的例子来支持解释,比如引用[1]中的数组修改和引用[2]中的基本类型传递。 最后,总结Java参数传递机制,强调不管是基本类型还是引用类型,都是值传递,区别在于传递的内容是值本身还是对象的地址。确保回答结构清晰,逐步引导用户理解,并引用提供的资料来增强可信度。</think>### Java参数传递机制详解 Java的参数传递机制是**值传递**,无论是基本数据类型还是引用类型,传递的都是变量存储的**值的拷贝**。以下分两种情况说明: --- #### 一、基本数据类型参数传递 基本数据类型(如int、double)传递的是**变量值的拷贝**,方法内部对参数的修改**不会影响原变量**。 ```java public static void main(String[] args) { int y = 10; doSome(y); System.out.println(y); // 输出10,原值未变 } public static void doSome(int x) { x = x * 3; // x变为30,但y不受影响 } ``` - **原理**:调用`doSome(y)`时,将变量`y`的值`10`拷贝给形参`x`,方法内修改的是拷贝后的`x`,与原变量`y`无关[^2]。 --- #### 二、引用类型参数传递 引用类型(如数组、对象)传递的是**对象地址的拷贝**,方法内通过地址修改对象属性会直接影响原对象,但重新赋值形参(指向新对象)**不影响原变量**。 **示例1:修改对象属性** ```java public static void main(String[] args) { int[] arrs = {10, 20, 30}; change(arrs); System.out.println(arrs[1]); // 输出222 } public static void change(int[] arrs) { arrs[1] = 222; // 修改原数组的第二个元素 } ``` - **原理**:形参`arrs`获得原数组地址的拷贝,指向同一对象,因此修改对象属性会影响原数组[^1]。 **示例2:重新赋值形参** ```java public static void change(int[] arrs) { arrs = new int[]{100, 200, 300}; // 形参指向新对象,原数组不受影响 } ``` - **结果**:原数组的第二个元素仍为`20`,因为形参的地址被修改为新数组,与原变量解耦。 --- ### 值传递引用传递的核心区别 1. **值传递**:传递的是值的拷贝,对拷贝的修改不影响原变量。 2. **引用传递Java不支持)**:直接传递变量本身的引用,方法内修改会影响原变量。 Java引用类型参数传递**本质仍是值传递**,传递的是地址值的拷贝,而非变量本身。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值