深入浅出java 函数参数传递原理

阅读本文之前,先做一道测试题。

import java.util.Arrays;
public class Test {
    public static int num=30;
    public static String astring="hello";
    public static String bstring="world";
    public static String cstring="me";
    public static String dstring="you";
    public static String[] aarray=new String[]{"er","cd","op","af"};
    public static void  main(String[] args){
        addNum(num);
        System.out.println("num="+num);
        changeString(astring, bstring);
        System.out.printf("astring=%s,bstring=%s\n", astring,bstring);
        swapString(cstring, dstring);
        System.out.printf("cstring=%s,dstring=%s\n", cstring,dstring);
        sortString(aarray);
        for (String string : aarray) {
            System.out.println(string);
        }
}
    public static void addNum(int number){
        number+=10;
    }
    public static void changeString(String a,String b){
        a=b;
    }
    public static void swapString(String c,String d){
        String temp=c;
        c=d;
        d=temp;
    }
    public static void sortString(String [] s){
        Arrays.sort(s);
    }
}

正确的输出结果是
num=30(没有改变)
astring=hello(没有变成world), bstring=world
cstring=me(没有变成you),dstring=you(没有变成me)
但是字符串数组aarray却变成了{“af”,”cd”,”er”,”op”}
为什么num没有变成40, astring的值没有变成world, cstring和dstring的值没有交换呢?
这是因为java函数传递参数的方式是值传递!!!!
对于8种基本数据类型(byte,short,int,long,float,double,boolean,char)
这些类型的值都存放在栈区,而其它的非基本类型的变量(例如String类实例,或者自定义的类实例等等)保存的都是该对象实例在堆区的地址, 这些值在栈区中存储,而形参得到的就是这些堆区的地址值(值传递体现在这里)
例如int i=30; 存储格式如下图所示。
 **图1** 存储基本数据类型结构图

其中AB,AC代表内存地址(为简单起见)
调用addNum函数时,实参num传递给形参number,并把num的值30传递给number, 即number=30, 因为是值的传递,所以另开辟一个内存地址存储该值,这里为AC(原来的内存地址为AB),在函数addNum里面操作的其实是内存AC对应的变量(即number),与原来的变量num没有任何关系,所以num的值没有变为40.
对应与函数changeString,其在内存中存储格式如下表所示。
**图2**   changeString函数简略存储结构
AB,AC,AD,AE代表栈区中的内存地址(存储的内容为对象在堆区的内存地址01,02), 01,02代表堆区中的内存地址(这里地址都做了简化)
形参a复制了astring的值, 形参b复制了bstring的值,
当进行a=b赋值操作的时候,AD里面的值由01变为02,如下图所示。
**图3 AD中的值改变**
这时AD,AE都指向02,即bstring ,但是原来的AB,AC中存储的值并没有改变所以astring还是hello
同理对于swapString函数,AD,AE中存储的值进行了互换, 即AD中的值为02,AE中的值为01,但是原来的AB,AC中存储的值并没有改变
所以cstring和dstring的值不会交换。

再来看sortString函数,存储图如下图示。
图4

对于形参s, 新开辟AC内存地址存储堆区的地址值01,
函数内部对s进行排序,这时操作的是堆区中01地址对应的内容,即原来aarray的内容,所以排序会对aarray起作用

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值