String对象创建细节
情况1:前两句代码只创建了一个字符串对象,因为s2的字符串内容与,s2相同,常量池中已经存在,不会重新创建对象
public class Demo {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "a" + "bc";//编译后就是abc
}
}
情况2: 当通过new方式创建String对象时,底层会有两个操作,首先会在堆中创建一个String对象,然后判断字符串常量池中是否有该字符串,若没有则再在常量池中创建一个对象,若有,则不创建
public class Demo {
public static void main(String[] args) {
String s3 = "123";
String s4 = new String("123");
}
}
情况3:当我们使用多个字符串对象拼接定义一个新的字符串时,效率非常低下
原因:因为String底层是一个由final修饰的char数组,数组长度一旦确定无法改变,在字符串拼接时我们并不确定最终长度,在拼接过程中会不断的创建新对象进行数组拷贝等操作,会占用大量堆内存,效率低
所以在我们的开发中,涉及字符串拼接我们一般使用StringBuffer类或者StringBuilder类
public class Demo {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2 + "c";
}
}
StringBuilder与StringBuffer类
当对字符串进行修改的时候,常常使用StringBuffer和StringBuilder类。 和 String 类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象,是对对象本身进行操作(返回当前对象)。
- StringBuilder是线程不安全的(不能同步访问),但是效率优于StringBuffer
- StringBuffer是线程安全的,但是效率低于StringBuilder,所以对线程安全没有要求是,常用StringBuilder
常用方法
StringBuilder和StringBuffer的常用方法几乎是一样的 如:
- append(str);追加
- insert(start,end);插入
- delete(start,end);删除
示例:
public class Demo {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(10);
sb.append("java");//java
sb.insert(4,"111");//java111
sb.delete(4,6);//java1
System.out.println(sb);
}
}