【学习笔记】String、StringBuffer、StringBuilder的理解

String

String有两种用法:

# 用法1
String a = "abc";//"abc"存在于常量池. 如果之后有String b = "abc";b也是指向常量池的"abc"
----------------------------------------------------------------------------------
# 用法2
String a = new String("abc");//"abc"存在于堆.如果之后有String b = new String("abc");b是在堆中重新开辟内存存储"abc"

------------------------------------比较-------------------------------------------

String a = "123";
String b = "123";
String c = new String("123");
String d = new String("123");

System.out.printf(a == b);      //true   因为比较的是变量(a、b)指向常量池的字符串的值

System.out.printf(a == c);      //false  比较的是引用,很明显a和c的引用是不一样的,c是后面new出来的

System.out.printf(c == d);      //false  道理差不多同上

System.out.printf(c.equals(d)); //true   比较的是引用指向的值;虽然c、d的引用不一样,但是他们指向的值是一样的。(这里要明确,这俩个"123"在堆中是不同一个内存的)

String赋值的时候,先在常量池中查找有没有当前需要的字符串,如果有,则直接指向;如果没有,则创建一个新的字符串。

#思考字符串被创建过程

String a = "ab";
String b = "abc";
a = a + "c";
System.out.printf(a == b); //false

//这里为什么  a = "abc",b ="abc"  怎么返回false

//因为a = a + "c";的时候,虽然a的值变为"abc"了,但a不是指向b创建在常量池中的"abc",而是重新建了一个"abc"的对象,这两个对象是不一样的地址,所以返回false。

//更加细节的话,我的理解是从赋值顺序来理解:
a = a + "c";   首先是a的值"ab"加上"c"组合成"abc"这个字符串,然后再存进常量池,再然后直接赋值给变量a。所以这里不像往常那样先查找常量池有没有自己需要的字符串,再进行指向。

StringBuffer

StringBuffer有append()、insert()、reverse()等常用方法。

StringBuffer e = new StringBuffer("abc");
e.append("d");
System.out.print(e);            //输出abcd
System.out.print(e.reverse());  //输出dcba  倒序输出
e.insert(1,"dd");               //在位置1插入dd
System.out.print(e);            //输出addbcd

StringBuffer的值不是在常量池中,而是在堆中,因它是new出来的对象,相应的值是在对中的,引用是在栈中。

就如上面的代码e.append("d");直接修改原来的对象中连接上新的字符串"d",而不是生成新对象。

StringBuilder

StringBuilder实际上与StringBuffer基本相似。不同的是StringBuffer是线程安全的;而StringBuilder没有线程安全功能,但性能高于StringBuffer。(俗话说,性能安全性同于鱼与熊掌不可兼得)

我们可以从其实现方法中去了解:

在实现方法中添加了synchronized,则说明给该方法加了锁,保证线程安全。

猜你喜欢

转载自blog.csdn.net/weixin_43548748/article/details/106736861