一、String类表示字符串。Java程序中的所有字符串文字(如“abc”)都作为此类的实例实现。 字符串是常量;它们的值在创建后不能更改。字符串缓冲区支持可变字符串。因为字符串对象是不可变的,所以它们可以共享。例如:
字符串str=“abc”; 相当于: char data[]={'a','b','c'};
因为字符串的底层是基于char数组实现,所以一些基于数组的操作模式字符串也是拥有的,例如:
public static void main(String[] args) {
String str = "中华人民共和国";
//字符串的长度
System.out.println(str.length());
//根据下标查询对应的字符
System.out.println(str.charAt(1));
//查询字符串首次出现的下标
System.out.println(str.indexOf("人"));
//截取字符串
System.out.println("str.substring(2,4) = " + str.substring(2,4));
}
以上便是基于数组的特性来衍生的功能。更多关于字符串的操作请参考源码或者官方文档。
需要注意的是,因为字符串是不可修改的常量,所以每次对字符串的修改都是创建了一个新的字符串,并将其对象的引用地址重新指向了新的字符串。
二、StringBuffer 是线程安全的可变字符序列。字符串缓冲区类似于字符串,但可以修改。在任何时间点,它都包含一些特定的字符序列,但序列的长度和内容可以通过某些方法调用来更改。
它提供的方法都经过synchronized关键字进行了修饰,意味着它是多线程情况下是线程安全的。
部分源码如下:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{
@Override
public synchronized int length() {return count;}
@Override
public synchronized int capacity() {return super.capacity();}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
@Override
public synchronized void trimToSize() { super.trimToSize();}
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
@Override
public synchronized char charAt(int index) {return super.charAt(index);}
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
@IntrinsicCandidate
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
}
StringBuffer继承于AbstractStringBuilder类,其本质是一个字节数组。部分源码如下:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
byte[] value;
/**
* The id of the encoding used to encode the bytes in {@code value}.
*/
byte coder;
/**
* The count is the number of characters used.
*/
int count;
private static final byte[] EMPTYVALUE = new byte[0];
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
value = EMPTYVALUE;
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
if (COMPACT_STRINGS) {
value = new byte[capacity];
coder = LATIN1;
} else {
value = StringUTF16.newBytesFor(capacity);
coder = UTF16;
}
}
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
int len = str.length();
ensureCapacityInternal(count + len);
putStringAt(count, str);
count += len;
return this;
}
}
注:该类的设计和集合中ArrayList设计思路一致。
三、StringBuilder类和StringBuffer实现方法一样,唯一区别的是StringBuilder得调用方法没有被synchronized关键字修饰,提高了字符串的操作效率,也意味着StringBuilder在多线程情况是线程不安全的。
部分源码如下:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{
@Override
public int compareTo(StringBuilder another) {
return super.compareTo(another);
}
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
@IntrinsicCandidate
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;
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@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;
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@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;
}
}