String クラスは、文字列を格納するために char[] 型の値を内部的に保持します。ソース コードは比較的単純です。
String の不変性は主に 3 つの側面に反映されます:
String クラスは Final 型として定義されており、継承できません
String の value[] は Final として定義されています
String で新しい String を生成するすべての操作は、Array.copy または System.copy を呼び出して、新しい String オブジェクトを生成します。 2. Constructor、String のコンストラクターは比較的単純ですが、以下はさらに特殊です
public String(String original) { this.value = original.value; this.hash = original.hash; } String(char[] value, boolean share) { // assert share : "unshared not supported"; this.value = value; }
public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // 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); }
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()); }
上記 2 つのコンストラクターの入力パラメーターはそれぞれ StringBuffer と StringBuilder で、最下層は Arrays.copyOf を呼び出します。唯一の違いは、StringBuffer がスレッドセーフであり、すべての呼び出しで synchronized キーワードを使用する必要があることです。
3. その他のメソッド
static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } if (targetCount == 0) { return fromIndex; } char first = target[targetOffset]; int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) { /* Look for first character. */ if (source[i] != first) { while (++i <= max && source[i] != first); } /* Found first character, now look at the rest of v2 */ if (i <= max) { int j = i + 1; int end = j + targetCount - 1; for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++); if (j == end) { /* Found whole string. */ return i - sourceOffset; } } } return -1; } static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { /* * Check arguments; return immediately where possible. For * consistency, don't check for null str. */ int rightIndex = sourceCount - targetCount; if (fromIndex < 0) { return -1; } if (fromIndex > rightIndex) { fromIndex = rightIndex; } /* Empty string always matches. */ if (targetCount == 0) { return fromIndex; } int strLastIndex = targetOffset + targetCount - 1; char strLastChar = target[strLastIndex]; int min = sourceOffset + targetCount - 1; int i = min + fromIndex; startSearchForLastChar: while (true) { while (i >= min && source[i] != strLastChar) { i--; } if (i < min) { return -1; } int j = i - 1; int start = j - (targetCount - 1); int k = strLastIndex - 1; while (j > start) { if (source[j--] != target[k--]) { i--; continue startSearchForLastChar; } } return start - sourceOffset + 1; } }
indexOf と lastIndexOf は、主に、index 関数と lastIndex 関数の基礎となる呼び出しであることがわかりますが、基礎となる実装には、依然として、特に強力な kmp アルゴリズムが実装されています。文字ごとにスキャンします。その中で、lastIndexOf は依然として continue startSearchForLastChar; を使用していますが、これは比較的まれです。
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; } } //如果找不到则返回this 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++; } //返回新的String,利用上述包内的非public构造函数 return new String(buf, true); } } return this; }
---リカバリコンテンツの終了---
以上がString ソースコードの解釈例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。