package wjd.stringtest; public class Test04 { public static void main(String[] args) { String s1 = "hello"; String s2 = "java"; show(s1,s2); System.out.println(s1+"...."+s2);//hello....java System.out.println("********************"); StringBuffer sb1 = new StringBuffer("hello"); StringBuffer sb2 = new StringBuffer("java"); show_2(sb1,sb2); System.out.println(sb1+"....."+sb2);//hellojava.....java } private static void show_2(StringBuffer sb1, StringBuffer sb2) { sb1.append(sb2); sb1 = sb2; } private static void show(String s1, String s2) { s2.replace('a', 'o'); s1 = s2; } }
(1) show方法中,String是怎么处理的?
1.1, main方法进栈,这个时候在字符串常量池中就会出现2个地址,这个假设s1地址的0x11,s2地址是0x22,在main方法中的s1和s2就分别指向了这2个地址
1.2, show方法进栈,show方法上的参数s1和s2也指向了上面对应的那2个地址(注意,方法参数上的s1,s2和main方法中的s1,s2是两个不同的东西,只是它们的变量名字相同而已),在show中,使用replace方法中,发生了替换的动作,这个时候,在字符串常量池中,会多出来一个属于jovo字符串的地址,这个假设是0x33,然后再将s2的地址赋值给s1,这里关键点出来了,由于是在show方法中进行的操作,当操作完毕之后,show方法中最后2个参数的地址都会是s2的地址,但是当show方法执行完毕之后,弹栈之后,在字符串常量池中,s1和s2的地址上的内容至始至终都没有发生变化,这个时候输出的就是hello和java.
(2)show_2方法中,StringBuffer是怎么处理的?
由于StringBuffer在底层是维护的一个可变的数组,所以在append的时候,会把s2中的内容追加到s1后面去,当new的时候,在堆内存中,会出现2个属于sb1和sb2的地址,然后在append的时候,s1的地址上的内容会变成hellojava,这里在sb1地址上的内容就发生了变化
再看后面的赋值,和String一样,方法内的赋值,方法没返回值,赋值的时候,不会导致堆内存中地址上面的内容的变化,所以你再怎么赋值,在最后方法弹栈的时候,对main方法中,程序的运行结果是没有变化的,所以最后输出的结果,是 hellojava 和 java.
----------------------------------------------------------------------------------------------------------------------------------------------
package wjd.stringtest; public class Test05 { public static void main(String[] args) { String s1 = "ab"; String s2 = "cd"; String s3 = "ab" + "cd"; String s4 = "abcd"; /* * 字符串连接的时候 * (1)如果是2个或者几个字符串常量进行+连接的时候,这时会产生一个新的字符串,这个新字符串产生的字符串常量池中 * (2)如果是2个或者几个字符串的引用变量进行+连接的时候,这个时候JVM会在底层产生StringBuffer字符串缓冲区对象, * String s5 = s1+s2,这时候s1会被append中字符串缓冲区中,接着s2再被append字符串缓冲区中 * 最后s5指向的不是s1+s2的结果,而是指向了StringBuffer容器 * 需要注意的是,在String和StringBuffer中,toString()这个方法都已经被复写了. */ String s5 = s1 + s2; System.out.println(s3 == s4);//true System.out.println(s5 == s3);//false System.out.println(s5 == s4);//false } }