又是一道面试题,来测试你的Java基础是否牢固。
题目:以下代码的运行结果是?
public class TestValue { public static void test(String str) { str="World"; //代码3 } public static void main(String[] args) { String string = "Hello"; //代码1 test(string); //代码2 System.out.println(string); //代码4 } }
运行结果是:Hello
解析:运行到达代码1时,系统在堆内存中开辟一个内存空间来生成一个String对象,并把这个对象的值设为“Hello”,然后将该对象分配给栈内存中的string变量来引用。变量string是被实际分配的引用对象,此引用保存着“Hello”在堆内存的地址值。
运行到达代码2,进入test(String str)方法,变量string的(引用)值的副本被传递给test方法。即将string变量的副本赋给test方法的形参str。此时变量string和test()方法内的变量str都是引用内存中的值为“Hello”的String对象。
运行到达代码3时,系统在堆内存中开辟一个内存空间来生成一个新的String对象,并把这个对象的值设为“World”,然后将该对象分配给栈内存中的str变量来引用。此时变量string仍然引用内存中的值为“Hello”的String对象,而test()方法内的变量str则引用内存中的值为“World”的String对象。
运行到达代码4时,test(String str)方法结束了,方法内的变量str作用消失,栈内存中没有了变量str,还有变量string。堆内存中值为“Hello”的String对象依然被变量string引用,值为“World”的String对象没有被引用。所以打印结果为:Hello
下面是内存示意图。
当然如果我们真的需要改变对象的值,可以尝试使用StringBuffer对象来处理。代码如下
public class TestValue { public static void main(String[] args) { StringBuilder string = new StringBuilder("Hello"); change(string); System.out.println(string); } public static void change(StringBuilder str) { str.delete(0, 5).append("World"); } }
打印结果为:World
读者也可以参考以下链接:
http://www.programcreek.com/2013/09/string-is-passed-by-reference-in-java/
==================================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================