[JAVA] String 소스 코드 에 대한 간단 한 설명

7566 단어 JAVA
String 소스 코드 에 대한 간단 한 설명
String 이라는 종 류 는 우리 가 가장 자주 사용 하 는 유형 중 하나 라 고 할 수 있 습 니 다. 몇 번 전에 면접 을 보 러 갔 는데 모두 String 의 바 텀 소스 에 대해 물 었 습 니 다. 대답 이 좋 지 않 았 습 니 다. 오늘 은 String 의 소스 코드 에 대해 이야기 하 겠 습 니 다.
String 클래스
public final class String implements java.io.Serializable, Comparable, CharSequence{...}

String 클래스 는 final 에 의 해 수식 되 었 습 니 다. 이 클래스 는 계승 할 수 없 음 을 나타 내 고 키워드 final 에 관 한 역할 이 있 습 니 다. 제 다른 글 [JAVA] 키워드 final 의 역할 을 옮 겨 주세요.특히 StringBuilder, StringBuffer 류 는 모두 final 에 의 해 수식 된다.
2. String 류 의 속성
  /** 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;

(1)char value[]
String 바 텀 의 저장 구 조 는 문자 형식의 배열 이자 final 에 의 해 수 정 됩 니 다. 따라서 이 문자 배열 이 생 성 되면 value 변 수 는 다른 배열 을 가리 킬 수 없 지만 value 배열 의 특정한 요소 의 값 을 바 꿀 수 있 습 니 다.
(2)int hash
hash 는 특정한 String 인 스 턴 스 의 해시 값 을 저장 하 는 데 사 용 됩 니 다. 해시 값 의 캐 시 라 고 할 수 있 기 때문에 String 은 HashMap 에 넣 고 key 로 사용 하기에 특히 적합 합 니 다.키 대 표를 삽입 할 때마다 키 의 해시 값 을 다시 계산 하지 않 고 키 의 캐 시 hash 값 을 직접 꺼 내 면 됩 니 다. 어느 정도 HashMap 의 효율 을 가속 화 합 니 다.
(3)long serialVersionUID
버 전의 일치 성 을 확보 하 는 데 사용 합 니 다.String 이 Serializable 인 터 페 이 스 를 실 현 했 기 때문에 직렬 화 된 ID 가 필요 합 니 다.직렬 화 할 때 이 ID 를 대상 과 함께 파일 에 기록 하고 역 직렬 화 할 때 이 클래스 의 ID 가 파일 의 ID 와 일치 하 는 지 확인 하고 일치 하면 버 전이 일치 하고 직렬 화 에 성공 했다 는 것 을 설명 합 니 다.
3. String 류 의 구조 함수
(1) 구조 함수 가 없 으 면 빈 문자열, 즉 '' 를 만 들 고 사용 하 는 곳 이 많 지 않 습 니 다.
    public String() {
        this.value = new char[0];
    }

(2) String 인 스 턴 스 를 받 는 구조 함수
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

(3) 문자 배열 을 받 고 Arrays. copy Of () 방법 으로 복사 합 니 다.
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

Arrays. copy Of () 방법 에 들 어가 면 System. array copy () 방법 이 호출 되 었 습 니 다. Arrays. copy Of () 방법 은 다음 과 같 습 니 다.
    public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

한편, System. array copy () 방법 은 로 컬 방법 으로 다른 언어 로 이 루어 진다.
상기 소스 코드 를 통 해 알 수 있 듯 이 이 구조 방법 은 들 어 오 는 문자 배열 의 인용 을 직접 사용 하지 않 고 이 배열 의 복사 본 을 사용 하여 String 류 의 불변성 을 확보 했다.이 배열 의 일부 요소 의 값 을 외부 에서 변경 함으로써 구 조 된 String 의 값 을 변경 할 수 없습니다.
마찬가지 로 toCharArray () 방법 에서 도 문자 배열 을 기반 으로 한 복사 본 을 되 돌려 주 고 value 배열 을 직접 되 돌려 주지 않 았 습 니 다.
    public char[] toCharArray() {
        // Cannot use Arrays.copyOf because of class initialization order issues
        char result[] = new char[value.length];
        System.arraycopy(value, 0, result, 0, value.length);
        return result;
    }

또한 System. arraycopy (), Arrays. copy Of () 간 의 효율 문제 가 있 으 므 로 제 다른 글 [JAVA] 배열 의 복사 효율 비교 도 참고 하 실 수 있 습 니 다.
(4) 문자 배열 을 받 고 offset 위치 부터 복사 합 니 다. 모두 count 비트 를 선택 하 십시오.
    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);
    }

다른 구조 함수 의 원 리 는 대동소이 하 므 로 여 기 는 더 이상 설명 하지 않 겠 다.
4. String 류 의 다른 방법
(1) equals () 방법
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

String 클래스 는 equals () 방법 을 다시 써 서 두 개의 String 실례 가 대표 하 는 문자열 이 같은 지 판단 합 니 다.
판단 규칙:
두 Stirng 인 스 턴 스 가 하나의 대상 이 라면 메모리 주소 가 같 으 면 트 루 로 돌아 갑 니 다.
이후 anObject 에 대해 유형 판단 을 하고 유형 은 String 인 후 계속 판단 하 며 그렇지 않 으 면 false 로 되 돌아 갑 니 다.
이들 의 길 이 를 판단 하고 같 으 면 계속 판단 하 며 그렇지 않 으 면 false 로 돌아간다.
두 글자 의 길이 가 같 은 후에 앞 뒤로 두 글자 배열 의 요소 가 같 고 똑 같은 지 비교 한 후에 true 로 돌아 갑 니 다.
equals () 방법 은 처음에 두 문자열 의 문자 배열 요 소 를 직접 비교 하지 않 았 고 긴 문자열 을 비교 할 때 많은 시간 을 절약 했다.
(2) compareTo () 방법
    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

두 문자열 을 비교 하면 정렬 할 수 있 습 니 다.String 클래스 에는 내부 클래스 인 Case Insensitive Comparator 도 있 습 니 다. compare () 방법 도 있 습 니 다. compare To () 측 과 달리 compare () 를 비교 할 때 두 문자열 의 대소 문 자 를 무시 합 니 다.
(3) hashCode () 방법
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

String 클래스 역시 hashCode () 방법 을 다시 써 서 String 인 스 턴 스 의 해시 값 을 계산 합 니 다.
해시 값 이 같은 두 문자열 은 반드시 같 지 않 습 니 다. 같은 문자열 의 해시 값 은 반드시 같 습 니 다.
이로써 String 클래스 는 equals () 를 다시 쓰 고 hashCode () 방법 도 다시 썼 다.두 가지 방법 사이 의 관계 에 관 해 서 는 나의 또 다른 문장 [JAVA] 을 참고 하여 왜 equals () 를 다시 쓰 려 면 hashCode () 를 다시 써 야 합 니까?
(4) intern () 방법
    public native String intern();

그것 은 현지의 방법 임 을 알 수 있다.
이 방법 을 호출 할 때 먼저 방법 구역 의 상수 탱크 에서 equals () 를 사용 하여 이 문자열 이 존재 하 는 지 찾 습 니 다. 존재 하면 이 문자열 의 인용 을 되 돌려 줍 니 다.존재 하지 않 을 때, 우선 이 문자열 을 상수 탱크 에 추가 하고, 이 문자열 의 인용 을 되 돌려 줍 니 다.
다음은 하나의 예 를 통 해 설명 한다.
package day1203;

//String    
public class StringTest {
    public static void main(String[] args) {
        String a = "abc";//  abc       
        String b = new String("abc");//  abc     
        String c = b.intern();//           abc,     ,        。
        System.out.println(a == b);//  false
        System.out.println(a == c);//  true
    }
}

문자열 생 성 및 저장 방식 과 관련 되 어 있 습 니 다. 제 다른 글 [JAVA] 문자열 생 성 및 저장 메커니즘 을 참고 하 십시오.
총화
String 클래스 에는 문자열 의 캡 처, 일치, 교체, 대소 문자 변환, 분할 등 재 미 있 는 동작 도 많이 있 습 니 다. 여기 에는 언급 되 지 않 았 습 니 다.이런 조작 들 은 확실히 자주 사용 되 는 것 이 므 로 모두 가 그들의 용법 을 이해 할 수 있 을 것 이 라 고 믿 으 니 여 기 는 더 이상 군말 하지 않 겠 다.
만약 또 약간의 의문 이 있다 면, 여러분 이 아래 에서 평론 하 시 는 것 을 환영 합 니 다. 저 는 반드시 제때에 회답 하 겠 습 니 다.

좋은 웹페이지 즐겨찾기