竹笋

首页 » 问答 » 灌水 » 程序员每日一题神奇的String的值传
TUhjnbcbe - 2023/9/1 20:20:00

每日一题,进步一点

答案为A

解析

这道主要考察的String的值传递和引用传递的问题。

我们都知道,java中,参数为基本类型时是值传递,参数为对象类型时是引用传递

按照这个思路,String不是基本类型,应该为引用传递,那么上面结果应该为10,但结果为什么是6呢,神奇不。

好,我们从java的内存模型说起,在内存模型中:

基本类型的变量放在栈里,

封装类型中,对象放在堆里,对象的引用放在栈里。

java在方法传递参数时,是将变量复制一份,然后传入方法体去执行。

这句话是重点,理解这句话,就会完全搞懂java的值传递和引用传递,它能解释一切。

我们先看下面一段代码

好,我们用上面那句话解释一下:

虚拟机分配一个内存地址给num,并且存了一个值0.虚拟机复制了一个num,我们叫它num_copy,num_copy和num的内存地址不同,但存的值都是0。虚拟机将num_copy传入方法changeNum,方法将num_copy的值改为1.changeNum方法结束,方法外打印num的值,由于num内存中的值并没有改变,还是0,所以结果还是0.再换个对象的示例:

好,依然用上面的思路解释:

jvm在堆中开辟了一个Product的内存空间,内存中包含proName和num。jvm在栈中分配给p一个内存地址,这个地址中存的是1中的Product的内存地址。jvm复制了一个p,我们叫他p_copy,p和p_copy的内存地址不同,但它们存的值是相同的,都是1中Product的内存地址。将p_copy传入方法,方法改变了1中的proName和num。方法结束,方法外打印p中变量的值,由于p和p_copy中存的都是1中Product的地址,但是1中Product里的值发生了改变,所以,方法外打印p的值,是方法执行以后的。我们看到的效果是对象类型的属性值发生了变化。按照这个思路,我们解释一下题目:

jvm在堆中开辟了一个SendValue的内存空间给sv,同时给属性str分配一个内存地址,存值为6调用change方法,传值为sv.str的一个复制体,并不是它本身,我们称它为strCopy。change方法中,将strCopy由指向字符串6的地址改为指向字符串“10”的地址。在change方法外打印sv.str,sv.str依然指向字符串6的地址,所以结果仍然是6从最终效果来看,String作为对象类型,呈现的是值传递的结果。

为了避免糊涂,直接理解这句话即可:java在方法传递参数时,是将变量复制一份,然后传入方法体去执行

至此,大家是不是明白了其中原因。

扩展

若要使题目中的最后输出为10,应该怎么修改代码?

ps:只能小改,改一行代码

1
查看完整版本: 程序员每日一题神奇的String的值传