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

本文深入解析Java中基本类型与引用类型的参数传递机制,通过实例演示了如何通过赋值运算符改变变量值,以及方法调用时参数传递的本质。

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

首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中。

一:搞清楚 基本类型 和 引用类型的不同之处

int num = 10;
String str = "hello";

这里写图片描述
如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为”引用”,引用指向实际对象,实际对象中保存着内容。

二:搞清楚赋值运算符(=)的作用

num = 20;
str = "java";

这里写图片描述

对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。如上图所示,”hello” 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)

三:调用方法时发生了什么?参数传递基本上就是赋值操作。

第一个例子:基本类型
void foo(int value) {
    value = 100;
}
foo(num); // num 没有被改变

第二个例子:没有提供改变自身方法的引用类型
void foo(String text) {
    text = "windows";
}
foo(str); // str 也没有被改变

第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
    builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。

第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
    builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。

重点理解为什么,第三个例子和第四个例子结果不同?

下面是第三个例子的图解:
这里写图片描述
builder.append(“4”)之后
这里写图片描述
下面是第四个例子的图解:
这里写图片描述
builder = new StringBuilder(“ipad”); 之后
这里写图片描述

转自知乎,链接:https://www.zhihu.com/question/31203609/answer/50992895

<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引用类型参数传递**本质仍是值传递**,传递的是地址值的拷贝,而非变量本身。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值