String
String 的理解
一、String实现了三个接口
serializable:说明String可以串行化的就是可以在网络上传输
comparable:说明String对象可以比较
CharSequence:String的字符序列
二、String是一个final类,就是不能被其他继承的
三、存放的是字符串常量里面的值是不能修改的,每次更新其实更新的是地址
String的两种创建方式
一、直接赋值:String str1=“zhouhao”;
str1先去常量池里面找,如果有,则直接指向,没有的话先创建然后再指向,str1最终指向的是常量池中的空间地址
二、通过new的方式:String str2=new String(“zhouhao”);
str2先会创建一个推空间,推空间维护了一个value属性,value然后再去常量池中找,有直接指向没有创建后指向,str2最终指向的是堆空间的地址
总结:这两种方式创建的String 指向的地址是不一样的
三、两种方式创建的示意图
四、代码演示
@Test
public void test_07(){
String a="zhouhao";
String b=new String("zhouhao");
// todo 因为String中重写了equals()方法 所有会比较值
System.out.println(a.equals(b));//true
// TODO a指向 常量池中的地址 b指向的是堆中 value(属性的地址) value在指向常量池中地址
System.out.println(a==b);//false
// todo intern() 这个方法最终会返回常量池中的地址
System.out.println(a==b.intern());//true
System.out.println(b==b.intern());//false
}
字符串的特性
@Test
public void test_07(){
String a="zhou";
String b="hao";
// todo 会在底层作一个优化 c="zhou"+"hao" 优化等价于 c="zhouhao"; 所以c还是直接指向 常量池的地址
String c="zhou"+"hao"; //直接指向池中的地址
// todo d会调用toString()底层用的还是new 会先指向 堆中的value value再去指向常量池中 “zhouhao”
String d=a+b; //会指向堆中的地址
System.out.println(c==d);//false
}
StringBuffer
一、String 和 StringBuffer、StringBuilder之间区别:
String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String
StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuffer(线程安全) 和 StringBuilder (非线程安全 )类之间的区别是 StringBuilder 不是线程安全的