Java中String、StringBuffer和StringBuilder的区别 ╰+攻爆jí腚メ 2022-12-29 04:32 118阅读 0赞 ## 1.String ## String类源码中有一行注释叫做: > **Strings are constant; their values cannot be changed after they** 翻译过来:字符串常量;它们的值不能在它们之后被改变 所以String对象是不可变的,String类中每一个看起来会修改String值的方法(如upcase等),实际上都是创建了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象丝毫未动 不仅效率低下,而且大量浪费有限的内存空间。 String a = "a"; //假设a指向地址0x0001 a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。 看下面的几行代码 public static void main(String[] args) { String result = null; for (int i = 0; i < 100; i++) { result += i + "ok"; } System.out.println(result); } 这是非常糟糕的代码,在运行的时候会创建许多string对象 ## **2.StringBuffer** ## **StringBuffer是可变类,**和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。 ## 3. StringBuilder ## StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzg5MzU0_size_16_color_FFFFFF_t_70][] 可以看到StringBuffer的方法都加上了同步锁来保证线程安全 ## 4.区别 ## 1)首先String、StringBuffer、StringBuilder在JDK中都被定义为final类,这意味着他们不可以被继承。 2)String最常见,与StringBuffer相比,String的性能较差,因为对String类型进行改变的时候都会重新生成一个新的String对象,这在字符串拼接操作时很明显,因此内容经常改变的字符串不应该使用String,如果不考虑多线程,则应使用StringBuilder。 3)StringBuffer生成一个对象后,在进行字符串拼接操作时,调用append方法即可,不会产生新的对象,仅对对象本身进行操作,性能比String要高。另外StringBuffer是线程安全的,因此适合在多线程中使用,也正因为如此,速度跟StringBuilder相比会比较慢。 4)StringBuilder的使用方法跟StringBuffer类似,但其是非线程安全的,因此一般常用于单线程,效率比StringBuffer高。 ## 5.代码执行时间效率对比 ## ### 5.1 环境版本 ### * 开发工具:Intellij IDEA 2020.2.3 * jdk:1.8.0\_211 * System: MacBook Pro (16-inch, 2019) 6C 32G ### 5.2 代码 ### public static void main(String[] args) { long start = System.currentTimeMillis(); String result = ""; for (int i = 0; i < 20000; i++) { result += i + "ok"; } long end = System.currentTimeMillis(); System.out.println("String耗时:" + (end - start)); start = System.currentTimeMillis(); StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 20000; i++) { stringBuffer.append(i).append("ok"); } end = System.currentTimeMillis(); System.out.println("StringBuffer耗时:" + (end - start)); start = System.currentTimeMillis(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 20000; i++) { stringBuilder.append(i).append("ok"); } end = System.currentTimeMillis(); System.out.println("StringBuilder耗时:" + (end - start)); } ### 5.3 执行结果 ### > String耗时:1855 > StringBuffer耗时:3 > StringBuilder耗时:1 ## 6.总结 ## 综上所述,选择哪个,需要从内存性能、线程安全、执行效率等多方面考虑,从上面的几条对比中可以得出答案。推荐单线程下使用StringBuilder [https://www.cnblogs.com/xiezc/p/11913830.html][https_www.cnblogs.com_xiezc_p_11913830.html] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzg5MzU0_size_16_color_FFFFFF_t_70]: /images/20221120/9e10cbd9dc734090a74f1dfe050a7a90.png [https_www.cnblogs.com_xiezc_p_11913830.html]: https://www.cnblogs.com/xiezc/p/11913830.html
还没有评论,来说两句吧...