String源碼解讀

String是常量,在定義以後不能被改變,字符串緩衝區支持可變的字符串。由於String對象是不可變的,因此能夠共享。java

定義

public final class String implements java.io.Serializable, Comparable<String>, CharSequence{}

String 是final類型,表示該類不能繼承,同時實現了三個接口java.io.Serializable, Comparable<String>, CharSequence正則表達式

屬性

private final char value[];

final類型的字符數組,用來存儲字符串的內容,由於被final修飾,因此String一旦初始化以後是不能被更改的。數組

private int hash;

緩存的hashCode值,默認爲0。緩存

private static final long serialVersionUID = -6849794470754667710L;
   
  private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];

String實現了Serializable接口,因此支持序列化和反序列化。網絡

java 的序列化機制是經過在運行時判斷類的serialVersionUID來驗證版本一致性。在進行反序列化時,JVM會把傳過來的字節流中的serialVersionUID與本地響應實體的serialVersionUID進行比較,若是相同就認爲是一致的,能夠進行反序列化,不然就拋出版本不一致的異常(InvalidCastException)。ide

構造方法

  1. 使用字符數組

當使用字符串數組建立的時候,會用的Arrays.copyOf方法和Arrays.copyOfRange方法。將源字符數組數據一一複製到String中的字符數組中。ui

//offset爲起始位置,count爲數量
  public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
  1. 字符串構造

使用字符串建立時,會將源String中的valuehash兩個屬性直接賦值給目標String。this

public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
  1. 字節數組構造
    char[]字符數組是以unicode碼來存儲的,Stringchar 爲內存形式,byte是網絡傳輸或存儲的序列化形式。能夠經過charset來解碼指定的byte數組,將其解碼成unicode的char[]數組,構造String。
String(byte bytes[]) 

String(byte bytes[], int offset, int length)

String(byte bytes[], Charset charset)

String(byte bytes[], String charsetName)

String(byte bytes[], int offset, int length, Charset charset)

String(byte bytes[], int offset, int length, String charsetName)
  1. 使用StringbuiderStringBuffer構造
    雖然存在當前的構造方式,可是和toString()方法相比,效率比較低。因此能夠直接使用toString()代替。
public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }

    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }

其餘方法

getBytes

String s = "你好,世界!"; 
byte[] bytes = s.getBytes();

這段代碼在不一樣的平臺上運行獲得結果是不同的。因爲沒有指定編碼方式,因此在該方法對字符串進行編碼的時候就會使用系統的默認編碼方式,好比在中文操做系統中可能會使用GBK或者GB2312進行編碼,在英文操做系統中有可能使用iso-8859-1進行編碼。這樣寫出來的代碼就和機器環境有很強的關聯性了,因此,爲了不沒必要要的麻煩,咱們要指定編碼方式。如使用如下方式:編碼

比較方法

boolean equals(Object anObject);
boolean contentEquals(StringBuffer sb);
boolean contentEquals(CharSequence cs);
boolean equalsIgnoreCase(String anotherString); //使用toUpperCase方法轉換成大寫,在進行比較
int compareTo(String anotherString);
int compareToIgnoreCase(String str);
boolean regionMatches(int toffset, String other, int ooffset,int len);  //局部匹配
boolean regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len);   //局部匹配
String s = "你好,世界!"; 
byte[] bytes = s.getBytes("utf-8");

其餘

ength(); //返回字符串長度

isEmpty(); //返回字符串是否爲空

charAt(int index;) //返回字符串中第(index+1)個字符

char[] toCharArray(); //轉化成字符數組

trim();// 去掉兩端空格

toUpperCase();// 轉化爲大寫

toLowerCase();// 轉化爲小寫

String concat(String str); //拼接字符串

String replace(char oldChar, char newChar); //將字符串中的oldChar字符換成newChar字符

//以上兩個方法都使用了String(char[] value, boolean share);

boolean matches(String regex); //判斷字符串是否匹配給定的regex正則表達式

boolean contains(CharSequence s); //判斷字符串是否包含字符序列s

String[] split(String regex, int limit;) //按照字符regex將字符串分紅limit份。

String[] split(String regex);
相關文章
相關標籤/搜索