String、StringBuffer、StringBuilder的区别?

区别

  1. String (JDK1.0) : 不可变字符序列 底层使用char[]存储
  2. StringBuffer (JDK1.0) : 可变字符序列、效率低、线程安全 底层使用char[]存储
  3. StringBuilder (JDK1.5) : 可变字符序列、效率好、线程不安全 底层使用char[]存储

注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。

源码分析
String str=new String(); -----------底层 : char[] value=new char[0]
String str=new String(“abc”);-----------底层:char[] value=new char[]{‘a’,‘b’,‘c’}
StringBuffer str=new StringBuffer();---------底层 char[] value=new char[16] 创建一个长度为16的数组
StringBuffer str=new StringBuffer(“abc”);---------底层 char[] value=new char[“abc”.length+16] 创建一个长度为"abc".length+16的数组

扩容问题: 如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。

开发建议

  1. 一般开发中,字符串如果不经常变化,优先使用String,如少量的字符串拼接操作,常量声明等。
  2. 在不存在线程安全问题的场景下(单线程),如果需要操作大量字符串,可以使用StringBuilder,避免使用 常量+变量来拼接字符串 如 Sting str=“abc”,str=str+“def”,这样会导致大量副本字符串对象再内存中,降低效率,影响程序性能
  3. 在线程不安全的情况下,如有大量字符串需要操作,应使用StringBuffer
  4. 如果能预知大小的话最好在new StringBuffer 或者StringBuilder 的时候设置好capacity,避免多次扩容的开销。扩容要抛弃原有数组,还要进行数组拷贝创建新的数组。减少内存操作,提高效率
String类详解

String类的特性

  1. String类: 代表字符串。java程序中的所有字符串字面值(如“abc”)都做为此类的实例实现
  2. String是一个final类,代表不可变的字符序列
  3. 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
  4. String对象的字符内容是存储在一个字符数组value[]中的。
    /**
     * 1.String类声明为final,不可继承
     * 2.String实现了Serializable接口:表示字符串支持序列化
     *         实现了Comparable接口:表示String可以比较大小
     * 3.String内部定义了final char [] value 用于存储 字符串数据
     * 4.String不可变性
     *         体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
     *              2.当对现有的字符串进行连接操作,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
     *              3.当调用String的replace()方法修改指定字符串或字符时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
     *
     * 5.通过字面量赋值(区别与new),此时字符串是存在常量池而不是堆内存
     * 6.字符串常量池中是不会存储相同内容的字符串的(内容相同,其实是一个地址)
     */

String不可变性体现

 @Test
    public void test01(){
        //字面量赋值  存在常量池
        String s1="abc";
        String s2="abc";
        //比较s1和s2的地址   true
        System.out.println(s1==s2);

        s2="hello";
        //abc
        System.out.println(s1);
        //hello
        System.out.println(s2);

        //这里其实用的还是s1的内存
        String s3="abc";
        //开辟了新内存
        s3+="def";
        // abcdef
        System.out.println(s3);
        //abc
        System.out.println(s1);

        //用的和s1一样的内存
        String s4="abc";
        //开辟新内存
        String s5 = s4.replace('a', 'm');
        //mbc
        System.out.println(s5);
        //abc
        System.out.println(s4);
    }

内存图:
内存图

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值