您的位置:首页 > 产品设计 > UI/UE

java中String、StringBuilder和StringBuffer理解

2017-02-19 16:27 519 查看
String、StringBuilder和StringBuffer理解

1>String

java.lang.String 类

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0

/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

/**
* Class String is special cased within the Serialization Stream Protocol.
*
* A String instance is written initially into an ObjectOutputStream in the
* following format:
* <pre>
*      <code>TC_STRING</code> (utf String)
* </pre>
* The String is written by method <code>DataOutput.writeUTF</code>.
* A new handle is generated to  refer to all future references to the
* string instance within the stream.
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
  ......


从以上JDK中String源码可以看出,String类被final修饰,在java中被final修饰的类是不能够被继承的,而且String类中的成员变量都被修饰成final。

而且可以看出String是通过char数组来实现保存字符串的。

public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}

public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */

while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}


以上是String类的部分成员方法,可以看出他们都不是在原有的String对象上操作的。只要对String对象进行改变,则就会创建新的String对象,对原有的对象并没有改变。

注意:String str1="abc" 和 String str2=new String("abc");有什么区别呢? 代码测试为证:

public class stringTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 = "abc";
String str2 = new String("abc");
String str3 = new String("abc");
String str4 = "abc";

System.out.println(str1 == str2);
System.out.println(str2 == str3);
System.out.println(str1 == str4);
}
}


结果是:



所以:string str1="abc"; 这样的语句是在编译时生成了字面常量和字符引用,然后在运行时蒋"abc"保存放到了运行时的常量池中,当下一个语句执行的时候就会从运行时常量池中查找 是否存在,如果存在则将他的引用指向了字面常量,如果没有就新开辟一个空间存放字面常量,并将引用指向他。

  有关new语句创建对象时,都是在堆中进行的,不会检查对象是否存在,所以每一个new语句都会创建一个新的对象。

2>StringBuilder

StringBuilder对String的改变操作是对原有对象进行操作的。

3>StringBuffer (线程安全)

StringBuffer和StringBuilder是类似的,之不过StringBuffer下的方法被snychronized修饰,线程安全。

这三个类是各有利弊,应当根据不同的情况来进行选择使用:

当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;

当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: