String 클래스는 문자열을 저장하기 위해 내부적으로 char[] 유형의 값을 유지합니다. 소스 코드는 비교적 간단합니다.
String의 불변성은 주로 세 가지 측면에 반영됩니다.
String 클래스는 최종 유형으로 정의되며 상속될 수 없습니다.
String의 값[]은 final로 정의됩니다
String에서 새 문자열을 생성하는 모든 작업은 Array.copy 또는 System.copy를 호출하여 새 String 개체를 생성합니다. 2. 생성자, 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()); }
위 두 생성자의 입력 매개변수는 각각 StringBuffer 및 StringBuilder입니다. 유일한 차이점은 StringBuffer가 스레드로부터 안전하고 모든 호출에서 동기화 키워드를 사용해야 한다는 것입니다.
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는 비교적 드물게 계속 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; }
---복구 콘텐츠 종료---
위 내용은 문자열 소스 코드의 해석 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!