【Java】值传递和引用传递

本文介绍了Java中参数传递的基本概念,包括基本类型和引用类型的差异、实际参数与形式参数的区别。值传递会复制实际参数的值,不改变原始变量;而引用传递则传递对象的地址,导致方法内修改会影响到原始对象。Java只支持值传递,但有时会出现类似引用传递的效果,这源于值传递中对引用地址的复制。

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

基本类型和引用类型

基本类型变量存储着变量的值。

引用类型变量存储的是对象的地址,地址指向堆中引用的对象。

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

基本类型使用“=”赋值,改变变量的值。

引用类型使用“=”赋值,改变变量的指向。

num=20;
str="cba";

此时,"abc"再无引用变量指向,成了垃圾,会在JVM GC的时候释放掉。


实际参数和形式参数

public static void main(String args[]){
    int actualParam = 10;
    func(10);
}

public static void func(int formalParam){
    System.out.println(formalParam);
}

方法头中的formalParam是形式参数,而调用方式时传进去的actualParam是实际参数。

将实际参数actualParam赋给形式参数formalParam就涉及到参数传递的问题。

有两种传递方式,一种是“值传递”,一种是“引用传递”,而Java是值传递。


值传递和引用传递

值传递,会把实际参数“复制”一份供函数调用。修改函数中的形式参数,不会修改实际参数的值

引用传递,直接把实际参数的地址给形式参数,修改形式参数的内容,也会修改实际参数的内容。

值传递

对于基本类型

public static void main(String[] args) {
    int num=10;
    System.out.println(num); //10
    change(num);             //20
    System.out.println(num); //10
}

private static void change(int num){
    num=20;
    System.out.println(num);
}

会将实际变量num复制一份,可以说是一个“新”的变量。 在“新”变量上做修改,不会影响原来的变量。

对于引用类型

第一种情况:形参实参指向不同地址。

public static void main(String[] args) {
    StringBuilder sb=new StringBuilder("abc");
    System.out.println(sb);   //abc
    change(sb);               //cba
    System.out.println(sb);   //abc
}

private static void change(StringBuilder sb){
    sb=new StringBuilder("cba")
    System.out.println(sb);
}

在方法中,新new了一个对象,让形参sb指向这个对象,对0x20的修改,自然不会影响到原来的对象。

第二种情况:形参实参指向同一地址。这种情况跟“引用传递”的效果一样,但是本质不同。

public static void main(String[] args) {
    StringBuilder sb=new StringBuilder("abc");
    System.out.println(sb);   //abc
    change(sb);               //cba
    System.out.println(sb);   //cba
}

private static void change(StringBuilder sb){
    sb.reverse();
    System.out.println(sb);
}

复制完后,两者都指向0x10处的"abc"对象,此时直接对形参sb执行reverse()方法,修改的就是原来的对象。虽然原来的对象被修改了,但它仍然是值传递复制了一份,只不过是两个变量指向同一片内存罢了。

再看一个例子,帮助理解

public static void main(String[] args) {
    int[] arr = { 1, 2, 3, 4, 5 };
    System.out.println(arr[0]);    //1
    change(arr);                   //0  
    System.out.println(arr[0]);    //0
}

public static void change(int[] array) {
    array[0] = 0;
    System.out.println(arr[0]);
}

道理与上面一样,两个变量指向同一个内存区域。

引用传递

那什么是引用传递?引用传递传递是变量的地址,注意是变量的“地址”,不是变量的值。实际上arr变量本身也有地址(0XAB),而引用传递就是把实际参数的地址给形式参数,就像下图这样。

为什么会出现值传递和引用传递效果一样的情况?对比一下上图,应该就能明白。因为Java复制的是实际变量的值,这个值,对于引用变量来说,就是指向的地址。

参考资料

https://blog.youkuaiyun.com/weixin_38719347/article/details/80961874

https://www.cnblogs.com/myCodingSky/p/3902284.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值