String类的独特之处
程序员文章站
2022-04-23 08:36:51
...
熟悉而又神奇的String
看到String,自然而然会想到字符串及其各种操作方法,这些都是String为了展现它的魅力,给我们看到的它的各种神奇功效。殊不知,在这些变来变去的招式后面,String还有个特别之处。
String 字符串是常量,不能进行修改。 String对象是不可变的,同时它也是很大方,虽然不能改变,但是可以共享内存。
现在还是来说说它的特别的地方,平时我们在new一个类的对象时,给不同的值,内容发生改变,但是其地址是没有变的<!--StartFragment -->
例如:Student stu = new Student(); stu.setAge(1); stu.setAge(2);而String不是,String在new的时候,会在堆内存中开辟一块新的内存,String 再次赋值时,不是将原有的内容进行修改,而是开辟一个新的内存空间,将新的值放入进去
String str = "abc"; String str2 = new String(data); System.out.println("str.equals(str2):"+str.equals(str2)); System.out.println(str==str2); 结果: str.equals(str2):true false所以一般String 一般不采用new的方式,而是直接进行赋值操作,不然很容易造成内存空间的浪费。
String类在给变量赋值一个字符串时,变量的值是放在静态共享池里,所以在产生新的变量时,JVM会检查共享池是否有”123“这个字符串,有的话就直接指向这个内存,没有就新建一个内存来存放这个新的字符串。但是这样不也是浪费了内存了吗?其实也不一定,如果有大量的String类型的变量,它们值都相同,都指向同一个内存,而当其中一个的值改变了,那么就只要为这个改变的变量重新开辟内存,其它的变量可以不发生变,这样相对于new的方式不是节约很多的内存么。
这样说可能有点拗口,举个例子(不是很恰当哈):现在有N个人没地方住 ,所以就为他们新建了一栋公寓,容纳了这些人。然后有一天,其中的一个人,挣了很多钱,不满意那个环境了,自己就搬进了新建的一栋别墅。其他人没有那么多钱还是只能住在公寓里面,这群人就只占了一栋公寓和一栋别墅的面积,而要是像new String那样,每个人一栋房子,就需要N栋房子的面积了,估计这地球也容纳不了那么多人了。
所以没必要的时候不要去new一个String对象,同时,不要频繁的修改String类型的变量的内容,这两种情况都会导致内存空间的浪费
当需要对大量字符串进行拼接时,又要发愁了,想啊,String类怎么这么霸道呀,不用着急,这不有了一个StringBuffer类(线程安全的可变字符序列)为String弥补了这个不足
String str3="123"; StringBuilder sb = new StringBuilder(str3); for(int i=0;i<5;i++){ sb.append("n"+i); } //将拼接完全的内容交换给Str3 str3 = sb.toString(); System.out.println("sb:"+sb); System.out.println(str3); 结果: sb:12345n0n1n2n3n4 12345n0n1n2n3n4在拼接大量字符串时,使用StringBuffer 保证了只有一个对象在进行操作,这些改变发生在一个类似于 String 的字符串缓冲区,不能修改,但可以通过append()等方法来改变该序列的长度和内容
除了StringBuffer类,有相同功能的还有StringBuilder类(线程不安全),该类被用作 StringBuffer 的一个简易替换,其效率比StringBuffer高,一般都会选择用StringBuilder类
看到这里应该已经知道了String的特别了吧,String类是一个又小气又大方的类,就是这样一个类在java中起着不可忽视的作用。就像一个调皮的小孩,皮的时候让人闹足了心;安静的时候,能让人看醉了。尽管这样的矛盾,但还是忍不住的喜欢。