Java随笔之String,StringBuffer与StringBuilder类

String,StringBuffer与StringBuilder的区别

String对象的创建的两种不同

摘要:String类型的实例的是定长(一旦生成不可变)的字符串,String 字符串变量 直接赋值的话是 看做字符串常变量存储在 “永久代”中,且多个字符串相同的常变量共享一片内存。 字符串变量调用new String("") 来创建变量的时候是,因为调用了new 所以该变量存储在“新生代”,而且独自占用一片内存。jdk1.8之后永久代叫做元空间Metasspace

` String text1 = “1234567”;
String text2 = “1234567”;
String text3 = new String(“1234567”);
String text4 = new String(“1234567”);

    System.out.println(text1 == text2);
    System.out.println(text1 == text3);
    System.out.println(text1 == text4);
    System.out.println(text3 == text4);`

"1234567"如果没有赋值给变量就是匿名对象,就是一个String类的对象可以直接调用String的方法。由于“1234567”是一个匿名的字符串常量对象地址赋值给text1和text2(String类的实例存储字符串实际上是通过char[]数组来存储的,且存储在字符串常量池里理论上内存的方法区里实际上在堆得永久代中),所以很明显text1和text2都是字符串常变量且二者共享一片内存,即满足 text1 == text2。但是String text3 = new String(“1234567”);
String text4 = new String(“1234567”);
明显是通过new新生成的内存来存储这个1234567字符串,而text3的值就是新生成的内存地址,text4亦是如此,且text3与text4是两片内存。所以不难预见text3 != text4.
在这里插入图片描述
运行结果如图所示

String的多个字符串拼接的两种方式的差异

第一种最简单便捷的+号,第二种调用append(String str)方法

`String text5 = “锄禾日当午”;
String text6 = “汗滴禾下土”;
String text7 = “床前明月光”;
text5 = text5+text6+text7;
System.out.println(text5);

    StringBuilder sb = new StringBuilder();
    sb.append("锄禾日当午");
    sb.append("汗滴禾下土");
    sb.append("床前明月光");
    String text8 = sb.toString();
    System.out.println(text8);`

第一种方法:text5+text6会生成一个新的字符串然后在内存中有地址, (text5+text6)+text7会生成一个新的字符串在内存中有地址,总的新字符串地址赋给text5后,原text5指向的字符串则变成垃圾, (text5+text6)生成的字符串也变成垃圾,由于String类型声明的字符串变量所存储的字符串为常量在字符串常量池里,存储在永久代里垃圾回收器GC不会及时回收,由此可见,利用+号拼接多个字符串时会产生很多新的字符串成为垃圾占用内存空间,在要拼接的字符串数据很多时尽量避免使用+来拼接字符串!

第二种方法:在StringBuilder与StringBuffer两个类里有append方法,String类没有。append方法返回的是StringBuilder或StringBuffe对象,Stringbuffer其实是动态字符串数组而append()是往动态字符串数组添加,String text1+text2则是将两个字符串拼接后放在新的内存地址中,然后StringBuffer与StringBuilder则是动态数组,拼接后内存地址还是动态数组的首地址,因而不存在产生内存垃圾占用内存的情况。由于append返回的是对象,所以徐璈调用toString方法变成字符串再打印输出。

至于StringBuffer 与 StringBuilder 的方法基本上相同两者拼接上操作时一致的,且与String三者间主要的区别就是:
StringBuilder 多线程同时操作的不安全的实现;(可能出现读写错误和死锁等情况)
StringBuffer 多线程安全的实现;
String 单线程,不能多线程同时操作。

推荐阅读为什么Java中的字符串被定义为不可变的以增强理解

猜你喜欢

转载自blog.csdn.net/qq_40694640/article/details/112598478