在http://www.cnblogs.com/aishangJava/p/7262577.html这里看到了一个题目,就去尝试了一下,代码如下:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package controller; /** * * @author Administrator */ public class change { public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; StringBuffer sb1 = new StringBuffer("hello"); StringBuffer sb2 = new StringBuffer("world"); change(s1, s2); System.out.println(s1 + "---" + s2); change(sb1,sb2); System.out.println(sb1+"---"+sb2); } public static void change(String s1, String s2) { s1 = s2; s2 = s1 + s2; } public static void change(StringBuffer sb1, StringBuffer sb2) { sb1 = sb2; System.out.println("first sb1:"+sb1); sb2.append(sb1); System.out.println("sb1:"+sb1+"\tsb2:"+sb2); } }
百度了一下,整理一下自己的理解:
在第一个change中,改变的只是形参的值,实参并没有改变;
第二个change中,由于StringBuffer定义时,sb1是存储在栈空间里的一个指向堆空间的一个地址,堆的值就是“hello”,当进行sb1=sb2的操作后,sb1中的地址就指向了sb2所指向的对象,所以在此时sb1的值为“world”,之后sb2进行append,随之s1的值变为“worldworld”。
至于为什么最后sb1输出的还是"hello",百度看了一下是这么回事:
要知道java中所有方法的实参都是传入变量的副本,所以对于基本类型参数,改变其副本值,原始参数不受影响,而对于引用类型参数,传入的是引用的副本,原始引用和副本引用指向同一个对象,操作副本引用指向的对象时,原始引用的对象也会随之改变(说白了,两个引用指向一个对象),但是 sb1=sb2,是说将这个sb1的副本引用设置为sb2的引用,使得副本引用sb1指向了sb2对象,但是原始引用sb1却没有参与任何操作,所以sb1不变。
时间: 2024-10-17 07:47:54