• 【Java】中的String、StringBuffer和StringBuilder的区别


    String

    在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

    需要注意的是,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。

    至于为啥是不可变,我们可以来看下面这个图,发现String是用final修饰的,导致了他的不可变。
    请添加图片描述
    接下来我们从内存的角度来看一下,操作String类型时候的内存变化

    请添加图片描述

    不难看出:初始String值为"Hello",然后在这个字符串后面加上新的字符串"world",这个过程重新在堆中开辟了空间,操作这俩个字符串开辟了3次内存空间,为了解决**经常性字符串相关的操作,**引入了StringBuilding和StringBuffer

    StringBuilding和StringBuffer的区别

    其实这个问题一直在面试中问,那么为啥要问这么简单的问题呢?

    其实这个一般只会在刚开始时候问,因为这个问题就是与线程安全有关,然后问怎么去保证线程安全?各种各样的锁,什么是锁,锁的机制,什么是死锁之类的问题,然后到synchronized,他的原理,怎么使用,synchronized和volatile区别是什么,为什么用volatile,上升到Java内存模型,然后并发包…………,所以说面试这个过程,首先要抛出一个问题,然后根据你的状态,进行循序渐进,那么我们现在就来看这个最简单的问题吧!

    与String类不同的是,StringBuffer和StringBuilding类的对象可以被多次修改,而不产生新的对象

    StringBuilding类在Java5中被提出,他与StringBuffer最大的不同在于他不是线程安全的,即是不支持同步访问。 有得必有失,StringBuilding由于不需要对应的锁机制(下面会提到),所以**其速度会更快一点,**在一般情况下我们更推荐使用StringBuilding,但是应用程序在要求线程安全的情况下,则必须使用StringBuffer类型

    关于字符串中的==

    //1
    String s1=new String("Hello world");            
    String s2=new String("Hello world");      
    System.out.println(s1==s2);  // false       
    //2
    String s3="Hello world";    
    String s4="Hello world";  
    System.out.println(s3==s4);  // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码1中局部变量s1,s2中存储的是JVM在堆中new出来的两个String对象的内存地址。虽然这两个String对象的值(char[]存放的字符序列)都是"Hello world"。 因此"=="比较的是两个不同的堆地址。

    代码2中局部变量s3,s4中存储的也是地址,但却都是常量池中"Hello world"指向的堆的唯一的那个拘留字符串对象的地址 。自然相等了。

    StringBuffer与StringBuilder的线程安全性问题

    这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。

    StringBuffer
    请添加图片描述

    StringBuilding

    请添加图片描述

    synchronized的含义:

    synchronized详解

    效率问题

    StringBuffer和StringBuilder可谓双胞胎,StringBuilder是1.5新引入的,其前身就是StringBuffer。StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。另外,JVM运行程序主要的时间耗费是在创建对象和回收对象上。

    总结

    1. 在编译阶段就能够确定的字符串常量,完全没有必要创建String或StringBuffer对象。直接使用字符串常量的"+"连接操作效率最高。

    2. StringBuffer对象的append效率要高于String对象的"+"连接操作。

    3. 不停的创建对象是程序低效的一个重要原因。那么相同的字符串值能否在堆中只创建一个String对象那。显然拘留字符串能够做到这一点,除了程序中的字符串常量会被JVM自动创建拘留字符串之外,调用String的intern()方法也能做到这一点。当调用intern()时,如果常量池中已经有了当前String的值,那么返回这个常量指向拘留对象的地址。如果没有,则将String值加入常量池中,并创建一个新的拘留字符串对象。

  • 相关阅读:
    SQL 如何提取多级分类目录
    lightdb22.3特性预览-增强对oracle内置函数的兼容
    OS X(MACOS) C/C++ 遍历系统所有的IP路由表配置。
    【C++游戏引擎Easy2D】想做游戏,这三个功能少不了(time+renderer+logger)
    【licode】srtp链接问题
    利用DMA的触发循环实现eTMR的PWM周期计数
    让GPT成为您的科研加速器丨GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图
    IB 化学考纲巨变 ,全面分析新旧考纲区别
    syslog和syslog watch实现
    Java中13 种锁的实现方式有哪些?
  • 原文地址:https://blog.csdn.net/weixin_45920495/article/details/125587283