目录
1.3.1用 + 拼接,底层调用的是StringBuilder的append方法
这个类是StringBuilder和StringBuffer的父类
StringBuffer类继承了AbstractStringBuilder类,通过synchronized实现线程安全
3.1 StringBuffer的append(String str)方法
StringBuilder类继承了AbstractStringBuilder类,没有synchronized,线程不安全
4.1 StringBuilder的一系列appen方法和toString()方法
1.String
1.1为什么String是不可变的
1.2 用 == 比较String对象
1.3 字符串的拼接
public class String与StringBuffer {
public static void main(String[] args) {
/**
* String的拼接
*/
String ss = "abc";
String s1 = ss.concat("de");
System.out.println(s1);//abcde
String s2 = ss + "ef";
System.out.println(s2);//abcef
// String s3 = ss.concat(null);NullPointerException
String s4 = ss + null;
System.out.println(s4);//abcnull,因为底层调用的是StringBuilder的append方法
}
}
1.3.1用 + 拼接,底层调用的是StringBuilder的append方法,可以拼null
编译后:
1.3.2 用concat拼接,不能拼null(NullPointerException)
1.拼接的字符串如果为空,直接返回当前字符
2.创建一个新的字符数组,长度为当前字符串加上拼接的字符串,并把当前字符串拷贝进去
3.把拼接的字符串加到字符数组的后面,getChars -> arraycopy -> native方法
4.用字符数组创建新的字符串对象并返回
1.4 字符串的创建
public class String与StringBuffer {
public static void main(String[] args) {
String str = new String();
System.out.println("!"+str+"!");//!!
}
}
2. AbstractStringBuilder
这个类是StringBuilder和StringBuffer的父类
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
@Override
public int length() {
return count;
}
public int capacity() {
return value.length;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
}
3. StringBuffer (线程安全)
StringBuffer类继承了AbstractStringBuilder类,通过synchronized实现线程安全
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
private transient char[] toStringCache;
//构造方法
public StringBuffer() {
super(16);//无参构造,字符数组初始容量为16
}
public StringBuffer(String str) {
super(str.length() + 16);//参数是字符串的构造
append(str);
}
@Override
//参数可以是:Object obj,String str,StringBuffer sb,AbstractStringBuilder asb,
//char[] str,boolean b,char c,int i,long lng,float f,double d
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
}
3.1 StringBuffer的append(String str)方法,可以拼null
1.调用父类AbstractStringBuilder的append(String str)的方法
2.拼接字符串是不是null,如果是null,走appedNull()方法
3.字符数组扩容,大小为count + len,再把原有的字符数组复制到里面去
4.把拼接的字符串加到字符数组的后面,getChars -> arraycopy -> native方法
跟String的concat不同的地方:这里直接操作的是value这个成员变量,并把这个字符数组返回,因此SringBuffer是可变的。而String是创建了一个新的String对象并返回。
public class String与StringBuffer {
public static void main(String[] args) {
/**
* StringBuffer 线程安全的,用synchronized修饰了
*/
//StringBuffer的append()方法
StringBuffer sb4 = new StringBuffer();
boolean b = false;
sb4.append(b);
System.out.println(sb4.toString());//false
String sss = null;
sb4.append(sss);
System.out.println(sb4.toString());//falsenull
}
}
3.2 StringBuffer的toString()方法
被transient修饰,不参与序列化和反序列化。
3.3.StringBuffer创建对象
空参构造:字符数组初始长度为16
带参构造:字符数组初始长度为:16+字符串长度
public class String {
public static void main(String[] args) {
StringBuffer sb3 = new StringBuffer();
String s5 = sb3.toString();
System.out.println("!" + s5 + "!");//!!
}
}
4.StringBuilder (线程不安全)
StringBuilder类继承了AbstractStringBuilder类,没有synchronized,线程不安全
4.1 StringBuilder的一系列appen方法和toString()方法
一系列的append方法,调用的是父类AbstractStringBuilder 的方法
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
@Override
public StringBuilder append(CharSequence s, int start, int end) {
super.append(s, start, end);
return this;
}
@Override
public StringBuilder append(char[] str) {
super.append(str);
return this;
}
@Override
public StringBuilder append(char[] str, int offset, int len) {
super.append(str, offset, len);
return this;
}
@Override
public StringBuilder append(boolean b) {
super.append(b);
return this;
}
@Override
public StringBuilder append(char c) {
super.append(c);
return this;
}
@Override
public StringBuilder append(int i) {
super.append(i);
return this;
}
@Override
public StringBuilder append(long lng) {
super.append(lng);
return this;
}
@Override
public StringBuilder append(float f) {
super.append(f);
return this;
}
@Override
public StringBuilder append(double d) {
super.append(d);
return this;
}
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
}
5.代码总结
5.1 关于拼接中null的总结:
StringBuffer、StringBuilder可以append一个null
String不能concat一个null,会报空指针
String可以+null(底层调用的是StringBuilder的append方法)
5.2 关于new的总结:
如果是空参构造创建了一个String对象,初始化为""
如果是空参构造创建了StringBuffer或StringBuilder对象,初始化一个字符数组,长度是16
打印出来都是""
public class String与StringBuffer {
public static void main(String[] args) {
/**
* String的拼接方法
*/
String ss = "abc";
String s1 = ss.concat("de");
System.out.println(s1);//abcde
String s2 = ss + "ef";
System.out.println(s2);//abcef
// String s3 = ss.concat(null);NullPointerException
String s4 = ss + null;
System.out.println(s4);//abcnull,因为底层调用的是StringBuilder的append方法
String str = new String();
System.out.println("!"+str+"!");//!!
/**
* String => StringBuffer
*/
String s = "hello";
//方式1:通过构造方法
StringBuffer sb1 = new StringBuffer(s);
System.out.println(sb1);//hello
//方法2:通过append方法
StringBuffer sb2 = new StringBuffer();
sb2.append(s);
System.out.println(sb2.toString());//hello
/**
* StringBuffer => String
*/
StringBuffer buffer = new StringBuffer("world");
//方法1:通过构造方法
String str1 = new String(buffer);
System.out.println(str1);//world
//方法2:通过toString方法
//任何引用类型调用toString方法都可以转成字符串
String str2 = buffer.toString();
System.out.println(str2);//world
/**
* StringBuffer 线程安全的,用synchronized修饰了
*/
//StringBuffer的toString()方法
StringBuffer sb3 = new StringBuffer();
String s5 = sb3.toString();
System.out.println("!" + s5 + "!");//!!
//StringBuffer的append()方法
StringBuffer sb4 = new StringBuffer();
boolean b = false;
sb4.append(b);
System.out.println(sb4.toString());//false
String sss = null;
sb4.append(sss);
System.out.println(sb4.toString());//falsenull
/**
* StringBuilder 线程不安全
*/
StringBuilder sb5 = new StringBuilder();
sb5.append(false);
System.out.println(sb5.toString());//false
String s6 = null;
sb5.append(s6);
System.out.println(sb5.toString());//falsenull
}
}