String类
*创建String对象:
方式一:直接赋值String s=“abc”;
方式二:调用构造器 String s=new String(“abc”);
1,方式一:先从常量池看是否有“abc”数据空间,如果有,直接指向,如果没有则重新创建,然后指向,s最终指向的是常量值里面的空间地址。
2,方式二:先在堆中创建空间,里面维护了value属性,执行常量池的abc空间。如果常量池里面没有“abc”,重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。
3内存分布图:
*字符串的特性:
1,String是一个final类,代表不可变的字符序列
2,字符串是不可变的。一个字符串对象一旦分配,其内容是不变的。
*下面代码中有几个对象
一共有3个对象,分别是 a="hello" b="abc" c=new String("helloabc")
小结:底层是StringBuilder sb=new StringBuilder();sb.append(a);sb.append(b);sb是在堆中,并且append是在原来的字符串的基础上追加的
重要规则:String c1="ab"+"cd";常量相加,看的是池,String c1=a+b;变量相加,是在堆中;
*StringBuilder和StringBuffer:
*StringBuffer
1,Java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。很多方法和String相同,但StringBuffer是可变长度的。StringBuffer是一个容器
*StringVSStringBuffer
1,String保存的是字符串常量,里面的值不能修改,每次String的更新实际上就是更改地址,效率低:private final char value[]【这个存放在方法区的常量池中】
2,StringBuffer保存的是字符串变量,里面的值可以修改,每次StringBuffer更新实际上更新的是内容,不用每次都修改地址,效率更高:char value[]【这个存放在堆中】
*String和StringBuffer相互转换
1,String-->StringBuffer
方式一:直接使用构造器的方式,将String字符串作为参数传入:StringBuffer sb=new StringBuffer(String);
方式二:通过调用StringBuffer的append()方法,将String字符串作为参数传入,
2,StringBuffer-->String
方式一:直接使用构造器,将StringBuffer作为参数传入:String s=new String(StringBuffer);
方式二:调用StringBuffer的toString方法,返回一个String类型的字符串
*Stringbuilder
1,一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步,该类被设计用作Stringbuffer的一个简易替换,用在字符串缓冲区被一个线程使用的时候,
2,在StringBuilder上主要操作的是append和insert方法,
*String,Stringbuffer和StringBuilder的比较
1,StringBuilder和Stringbuffer非常相似,均代表可变的字符序列,而且方法一样
2,String:不可变得字符序列,效率低,但是复用率高
2,StringBuffer:可变字符序列,效率较高(增删),线程安全
3,StringBuilder:可变字符序列,效率最高,线程不安全
*String,Stringbuffer和StringBuilder的选择
1,如果字符串存在大量的修改操作,一般使用StringBuilder和StringBuffer
2,如果字符串存在大量的修改操作,并在单线程的情况下,使用StringBuilder
3,如果字符串存在大量的修改操作,并在多线程的情况下,使用StringBuffer
4,如果我们字符串很少有修改,被多个对象引用,使用String