String
String str1 = "hello"; str1 = str1 + "world"; System.out.println(str1);对此代码进行反汇编
可以看出来在其中调用了invokespecial 构造了一个StringBuilder对象,说明String字符串相加其实是通过StringBuilder的append方法进行的。其顺序为。
1.先将第一个字符串hello转化为StringBuilder
2.将第二个字符串world通过append方法追加进去。
3.调用StringBuilder的toString方法
因为StringBuilder的toString方法new了一个新的String对象给目标,所以这可就可以解释,为什么追加前的str1和追加后的str1地址不同了。
StringBuilder
StringBuilder str3 = new StringBuilder("hello"); str3.append("world"); System.out.println(str3);对此代码进行反汇编
可以看出来其只是调用了一次append追加,说明在字符串追加上面,StringBuilder有着天然优势,其没有生成新的对象。
StringBuffer
StringBuffer str2 = new StringBuffer("hello"); str2.append("world"); //3代表下标,可以在指定下标插入字符串 str2.insert(3, "hehe"); System.out.println(str2);对此代码进行反汇编
可以看出来其和StringBuilder基本相同,没有多余的对象产生。
它们三个的优缺点
由上面的实例可以看出来,String在追加的时候会产生新的对象耗费空间,所以在需要频繁的追加的时候,我们不使用String而使用StringBuilder和StringBuffer,因为其没有新的对象产生。
那么问题来了
StringBuilder和StringBuffer我们到底选哪一个呢?
查看StringBuilder源码
StringBuffer源码
可以看到StringBuffer的方法中有一个修饰符synchronized(synchronized是Java中的关键字,是一种同步锁)这个修饰符的意思就是这个方法是线程安全的,所以StringBuffer适用于多线程,而StringBuilder适用于多线程,因为在多线程中如果多个线程同时访问一个StringBuilder,又因为其没加锁,所以可能会出现错误,而在单线程中适用StringBuffer因为频繁的加锁解锁会影响代码的效率。
String类中的一些方法
1.subString
2.charAt
3.indexOf
查找字符
查找字符串