java中的String,StringBuffer,StringBuilder

来源:互联网 发布:润桐数据 编辑:程序博客网 时间:2024/06/14 17:26

1、关于String类:

1、string的本质:

这里写图片描述
通过String的源代码能学到很多知识。


这里写图片描述


String类是一个常量,一旦创建后就不能改变。如果想要改变可以用String buffers的相关操作。
String的本质是由char字符组成的字符数组;
在注释中这样写:
String str =”abc”;
相于:
char data[]={‘a’,’b’,’c’};
String str =new String(data);

2、String与内存

首先要明确String在内存中的保存的地方:
1、字符串池;
2、堆;
3、常量池;


  1. 8种基本数据类型保存在栈中,通过new产生的对象实例保存在堆中。
  2. String不属于基本数据类型。
  3. String str=”abc”;创建保存到字符串池中对象;
  4. String str1=new String(“abc”);创建的对象实例保存在堆中,另一个对象保存在常量池中;

    public static void main(String[] args) {        // TODO Auto-generated method stub        String str = "abc";// 在字符串池中创建;        String str1 = "abc";// 在字符串池中创建;        String str2 = new String("abc");// 在堆中创建;        String str3 = new String("abc");// 在堆中创建;        String str4 = "a";// 在字符串池中创建;        String str5 = "bc";// 在字符串池中创建;        // 通过 + 链接的问题:        //问题1:如果链接的全部是字符串池中的,则不会创建新的对象        //问题2:如果链接的有不是字符串池中的,则会在堆创建新的对象;        String str6 = str4 + str5;        String str7 = "a" + "bc";//中会在字符串池中创建;        // true,str和str1都是在字符串池中的,字符串池中如果没有则会创建,如果有了则不会创建;        // 也就是str,str1是同一个对象        System.out.println("str:str1---- " + (str == str1));        // false; str在字符串池中,str2在堆中;        System.out.println("str:str2---- " + (str == str2));        // false;str2和str3分别为在堆中不同的对象;        System.out.println("str2:str3---- " + (str2 == str3));        // false;str为字符串池中的,str6最终形成的在堆内存中;        System.out.println("str:str6---- " + (str == str6));        // ture;str7全部是在字符串池中的,因此str与str7为同一对象;        System.out.println("str:str7---- " + (str == str7));    }

运行结果:
这里写图片描述

3、String创建对象的问题

经典问题: String str = new String(“abc”); 产生几个对象?
1、String str=”abc”;创建的对象保存在字符串池中,在字符串池中如果有了“abc”,则不会创建新的对象;
2、String str = new String(“abc”); 它的一个对象保存在堆中,另外还产生一个对象,就是在常量池是的对象。如果常量池中没有,则创建,如果有则不会创建。因此上面的问题是可能创建一个对象,也可能创建两个(在常量池中不存在的情况下)
3、String =”a”+”bc”;通过上面的可知,创建一个对象,在字符池中

4、字符串不可变产生的问题

String类这样的设计有很多的优点使用简单,易用,易维护和扩展。但在String的不可以变类,也带来也问题。对象一旦创建就不能改变内存状态,如果要把字符串连接或者改变,只能在串接后产生一个新的对象,也就是如果每执行一次串接都会创建新的对象,性能问题随之而来。
为了解决这个问题,便产生了StringBuffer。

5、StringBuffer

1、StringBuffer类:
这里写图片描述
继承于AbstractStringBuilder,下面对于StringBuffer的描述:
这里写图片描述
一个线程安全的可变序列
一个字符串缓冲区,但可以修改。在任何时候它包含一些特殊序列字符时,它的长度可以通过一些方法修改。
在多线程下字符串缓存是安全的。它的方法全部都是同步的。
构造:
这里写图片描述
在没有字符默认长度为16个字符大小;


2、StringBuffer是如何扩容的?
首先它调用父类方法:
这里写图片描述


在方法中又调用ensuerCapacityInternal();
这里写图片描述


最终走到这个方法中:
这里写图片描述

从StringBuffer中可以看出:
在这个方法中,首先开辟一个新的字符串大小,为 int newCapacity = value.length * 2 + 2;如果添加后的大小比这个还要大,则把添加后的大小直接给新。

6、StringBuilder

StringBuilder是非线程安全的,在jdk1.5提供的API。在这里不用多叙述StringBuilder,因为它和StringBuffer用法和内部实现原理基本一样,只是StringBuffer的方法前面一般都加上有synchronized。线程非安全是指,当多个线程同时操作这个字符串的时候,可能发生脏的,重读或者其他错误的情况。

2 0
原创粉丝点击