10
2021
02

String详解(一):如何理解String

引入问题:



 


(一)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操作产生的对象。

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。