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

来源:互联网 发布:淘宝网的性用品有用吗 编辑:程序博客网 时间:2024/04/28 11:34

1、String

String:字符串常量,字符串长度不可变。Java中的String是immutable(不可变)的。

String类的包含如下定义:

    /** The value is used for character storage. */      private final char value[];            /** The offset is the first index of the storage that is used. */      private final int offset;            /** The count is the number of characters in the String. */      private final int count;  


用于存放字符的数组被声明为final的,因此只能被复制一次,不可再更改。

2、StringBuffer

     StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串进行修改,处于效率考虑最好使用StringBuffer,如果想装成String类型,需要调用StringBuffer的toString()方法。

     StringBuffer:java.lang.StringBuffer是线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法可以调用改变该序列的长度和内容。可将字符串缓冲区安全地用于某个线程。

3、StringBuilder

     StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符串序列的变长数组。java.lang.StringBuilder是一个可变的字符序列,此类提供一个与StringBuilder兼容的API。但不保证同步,该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。

其构造方法如下:

构造方法描述StringBuilder()创建一个容量为16的StringBuilder对象(16个空元素)StringBuilder(CharSequence cs)创建一个包含cs的StringBuilder对象,末尾附加16个空元素StringBuilder(int initCapacity)创建一个容量为initCapacity的StringBuilder对象StringBuilder(String s)创建一个包含s的StringBuilder对象,末尾附加16个空元素
在大部分情况下,StringBuilder > StringBuffer。这主要是由于前者不需要考虑线程的安全问题。

4、三者区别

     String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。

4.1 可变与不可变

     String类中使用字符数组保存字符串,如下就时,因为有final修饰,所以可以知道String对象是不可变的:

   private final char value[];
     StringBuilder与StringBuffer都继承AbstractStringbuilder类,在这个类中也是使用字符数组保存字符串,如下就时,可以知道这两种对象都是可变的:

   char[] value;
4.2 是否多线程安全

     String中的对象是不可变的,也就可以理解为常量,显然是线程安全的。

     AbstractStringBuilder是StringBuilder和StringBuffer的公共父类,定义了一些字符串的基本操作,入expandCapacity/append/insert/indexof等公共方法。

     StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的,StringBuilder并没有对方法加入同步锁,所以是非线程安全的。

4.3 StringBuffer与StringBuilder的共同点

     StringBuilder和StringBuffer用公共父类AbstractStringBuilder(抽象类)。

     抽象类与接口的其中一个区别:抽象类可以定义子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的声明和长两天的定义。

     StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append()。只是StringBuffer会在方法上加synchronized关键字,进行同步。

     如果写程序不是多线程的,那么使用StringBuilder的效率会高于StringBuffer。

5、使用场景

5.1 使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明,少量的变量运算。

5.2 使用StringBuffer类的场景:在频繁进行字符串运算(如字符串拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,例如XML解析、Http参数解析和封装。

5.3 使用StringBuilder类的场景:在频繁使用字符串运算(如字符串拼接、替换、删除等),并且运行在单线程环境中,则可以考虑使用StringBuilder。如SQL语句的拼接、JSON封装等。







0 0
原创粉丝点击