先看一段代码,是我遇到过的一道面试的笔试题:
1 /** 2 * ***面试题 3 */ 4 public class StringBufferTest { 5 public static void main(String[] args) { 6 int i = 10; 7 test(i); 8 System.out.println(i);//10 9 StringBuffer str = new StringBuffer("str");10 test2(str);11 System.out.println(str.toString());//str_add12 test3(str);13 System.out.println(str.toString());//str_add14 }15 16 public static int test(int m) {17 m = 30;18 return m;19 }20 21 public static StringBuffer test2(StringBuffer str2) {22 str2.append("_add");23 return str2;24 }25 26 public static StringBuffer test3(StringBuffer str3) {27 str3 = new StringBuffer("java");28 return str3;29 }30 31 }
值传递:
i的值并不会因为test方法中将输入参数赋值为30而变成30
所以执行方法test(i)后打印i的值还是之前的值10
具体过程如下:
变量i---->[存放值10]
执行调用test(i)方法的时候,内存中是这样的情形:i把自己值在内存中复制一份,然后变量m指向这个被复制出来的10。
变量i---->[存放值10]
↓进行了一次值复制
变量m--->[存放值10]
这时候再执行到17行的时候,变量m的被赋值为30,而这一步的操作已经跟i没有任何关系了。
变量m--->[存放值30]
引用传递:(全局变量变量时候要特别注意改变之后是否会影响其他地方)
str传递给test2方法是str的引用,所以str2的改变会影响str的值
所以执行方法test2(str)后打印str的值变成str_add
具体过程如下:
变量str---->[存放值"str"]
执行test2(str),注意,这里就与值传递有了本质的不同:调用test2(str)时,变量str2也指向了str指向的内存空间,而不是指向str的一个拷贝。
变量str \
-->[存放值"str"]
变量str2 /
于是,第22行对str2调用append方法,改变str2指向的内存空间的值,str的值也就随之改变了。
变量str \
-->[追加为"str_add"]
变量str2 /
思考为什么test3(str)后打印str的值不是java而是str_add?
主要原因在于:str3 = new StringBuffer("java");这行代码
出现类似传入值拷贝的变化:new方法并没有改变str指向内存的内容,而是在内从中开辟了一块新的空间存放串"java",同时str3指向了这块空间。
具体过程如下:
程序执行到第12行,str指向一个存放着"str_add"的内存空间。
变量str---->[存放值"str_add"]
调用test3(str),将str3指向str指向的内存空间,也就是传入str的引用。
变量str \
-->[存放值"str_add"]
变量str3 /
执行27行,这里就出现了类似传入值拷贝的变化:new方法并没有改变str指向内存的内容,而是在内从中开辟了一块新的空间存放串"java",同时str3指向了这块空间。
变量str---->[存放值"str_add"]
str3原有的引用被切断
变量str3--->[另一块存放"java"的空间]
以上是Java的引用和值传递详解的详细内容。更多信息请关注PHP中文网其他相关文章!