转载请注明出处:http://blog.csdn.net/jeffleo/article/details/52194050
引入问题:
(一)String和基本数据类型的区别:
首先要理解String是一个对象,而不是基本数据类型。String是存放在char[]中的,char[]跟所有的对象一样存放在堆,而基本数据类型存放于堆栈中。
(二)理解String不可变:
String q = "hello";
println(q);
String qq = upcase(q);
println(q);
println(qq);
//上述代码的输出结果
hello
hello
HELLO
把q传递到upcase中,传递的是什么?值还是引用?
如果是值,upcase调用后会改变q的值,就是说此时qq和q的值都为HELLO,因此传递的必然是q的一份复制的引用。从另一个想法考虑,这说明了String是不可变的,把String对象作为传递参数时,实际原来的对象依然指向原来的物理位置,无论如何都不能改变此引用的值。
(三)再理解String不可变
String ss1 = "how " + "old " + "are " + "you";
println(ss1);
StringBuilder builder = new StringBuilder();
builder.append("how ").append("old ").append("are ").append("you");
println(builder.toString);
//结果
how old are you
how old are you
两种都能实现同样的结果,有什么不同?
第一种方式实际在内部就是使用StringBuilder的append来完成的!那我们对于这种需求的时候应该使用哪种方式来完成(例如在http中写url的get方式的参数时需要不断在后面追加参数)?
显然是第二种!因为String不可变,因此不断得使用+操作,会不断得创建新的String对象,产生许多我们不需要的中间对象,而我们需要的只是最后一个String对象(最致命的是,String很耗内存)。而StringBuilder不同,它在append的时候不会产生新的对象,而**在最后的toString才会创建一个String对象。
(四)两种创建String的方式
String a = "a"和String a = new String("a")有什么不同?
从对象个数来看
第一个显然只有一个对象,第二个却有两个对象"a"和new String("a")
那应该使用哪一种呢?先看看这个问题:
String a = "a"
明显只有一个对象
String ab = "cd";String ac = "cd";
这里还是一个对象!
为什么?因为jvm中存在一个String池,存放着String对象,用于共享使用,提高效率。当执行ab的语句时,会调用equal去跟String池中比较看存不存在“cd”这个值得对象,如果存在,则返回这个对象给ab,如果不存在,则把这个值得对象加入String池。当执行完ab,再执行ac时,由于String池已经存在值为"cd"的ab对象,因此会把该对象的引用赋给ac。这么看,String池的存在很合理。但是String池只能添加使用引号包含文本的方式产生的对象,而不能添加使用new操作产生的对象。