java.lang.String 류 의 불변성 을 깊이 이해 하 다

1.문자열 String 의 불변성
무엇이 불가 변류 입 니까?
이렇게 이해 하면
        한 대상 이 생 성 이 끝 난 후에 상 태 를 바 꿀 수 없고 구성원 변 수 를 바 꿀 수 없습니다.(구성원 변수 가 기본 데이터 형식 을 포함 하면 이 기본 데이터 형식의 값 은 바 꿀 수 없습니다.인용 형식 이 포함 되 어 있 으 면 이 인용 형식의 변 수 는 다른 대상 을 가리 킬 수 없습니다)
가 변 클래스 는 인 스 턴 스 가 수정 할 수 없 는 클래스 일 뿐 입 니 다.모든 인 스 턴 스 에 포 함 된 모든 정 보 는 이 인 스 턴 스 를 만 들 때 제공 되 고 대상 의 전체 생명 주기 에 고정 되 어야 합 니 다.클래스 가 변 하지 않도록 다음 다섯 가지 규칙 을 따라 야 합 니 다.
  • 대상 상 태 를 수정 할 수 있 는 어떤 방법 도 제공 하지 마 십시오
  • 보증 클래스 가 확장 되 지 않 습 니 다.일반적인 방법 은 이러한 종 류 를 final 이 라 고 부 르 고 하위 화 를 방지 하 며 이러한 변 하지 않 는 행 위 를 파괴 하 는 것 입 니 다
  • 모든 도 메 인 을 final
  • 모든 도 메 인 을 사유 로 합 니 다.클 라 이언 트 가 도 메 인 에서 인용 한 가 변 대상 에 접근 할 수 있 는 권한 을 얻 는 것 을 방지 하고 클 라 이언 트 가 이 대상 들 을 직접 수정 하 는 것 을 방지 합 니 다
  • 모든 가 변성 구성 요소 에 대한 상호 배척 방문 을 확보 합 니 다.클래스 가 가 변 대상 을 가리 키 는 도 메 인 이 있다 면 이러한 클 라 이언 트 가 이 대상 을 가리 키 는 인용 을 얻 지 못 하도록 확보 해 야 합 니 다.
  • API 문서 뒤 집기:
    
    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        // value     final   
        private final char value[];
        ...
    }
    
    String 클래스 의 대표 문자열 입 니 다.자바 프로그램의 모든 문자열 글자 액면가(예 를 들 어 abc)는 이러한 인 스 턴 스 로 이 루어 집 니 다.이 글자 들 의 액면 가 는 모두"방법 구역"에 직접 저 장 된 에 저 장 됩 니 다.
    문자열 은 상수 입 니 다.그들의 값 은 생 성 후 이 므 로 공유 할 수 있 습 니 다.예 를 들 면:
    
    String str = "abc";
    그 러 자 왜 String 이 변 하지 않 는 지 의문 이 들 었 다.하지만 제 코드 에 서 는 String 이 자주 바 뀌 어 요.다음 과 같 습 니 다.
    
    String str = "HELLO";
    str = "WORLD";
    System.out.println(str);    // WORLD
    이렇게 조작 하면'HELLO'대상 을'WORLD'대상 으로 바 꾸 는 것 이 아 닙 니까?
    문자열 의 내용 이"HELLO"에서"WORLD"로 변 한 것 처럼 보이 지만,실제로는 새로운 문자열 이 생 성 되 었 습 니 다.
    
    String str = "HELLO";
    System.out.println(str.hashCode());  // 68624562
    str = "WORLD";
    System.out.println(str.hashCode());  // 82781042
    
    변수 str 전후의 hashCode 값 이 다 르 기 때문에 str 가 변경 전후 에 서로 다른 대상 을 가리 키 고 있 음 을 설명 합 니 다.따라서 변수 str 는 서로 다른 대상 만 가리 키 고 문자열'HELLO'대상 자 체 는 변 하지 않 았 습 니 다.
    변수 str 의 지향 은 다음 그림 과 같 습 니 다(jdk 1.8:문자열 상수 가 쌓 여 있 습 니 다).
    在这里插入图片描述
    우리 도 javap 명령 을 사용 하여 class 의 상수 탱크 를 볼 수 있 습 니 다:
    
    javap -c -v StringTest.class
    실행 후 상수 탱크 정 보 는 다음 과 같 습 니 다.
    在这里插入图片描述
    상수 탱크 에서 볼 수 있 듯 이 두 개의 문자열 대상 이 있 습 니 다:HELLO,WORLD
    [총 결]:String 대상 더미 에서 만 들 면 수정 할 수 없습니다.그리고 String 류 의 모든 API 방법 은 문자열 자체 의 값 을 바 꾸 지 않 고 새로운 문자열 대상 을 되 돌려 줍 니 다.
    2.String 디자인 이 가 변 적 이지 않 은 장점
    'String 은 가 변 적 이지 않다'는 것 을 알 게 된 후,사람들 은 왜 String 을 가 변 적 이지 않 은 것 으로 설계 해 야 하 는 지 의 심 스 럽 지 않 습 니까?이렇게 하면 또 무슨 좋 은 점 이 있 습 니까?
    주로 다음 과 같은 몇 가지 측면 에서 고려한다.
  • 보안 신뢰성:문자열 은 자바 응용 프로그램 에서 광범 위 하 게 응용 된다(예 를 들 어 사용자 이름,비밀번호,연결 url,네트워크 연결 등).JVM 클래스 로 더 는 클래스 를 불 러 올 때 도 광범 위 하 게 사용 된다.따라서 String 류 를 보호 하 는 것 은 전체 프로그램의 안전성 을 향상 시 키 는 데 중요 합 니 다.
  • 캐 시:문자열 은 가장 광범 위 한 데이터 구 조 를 사용 하고 대량의 문자열 의 생 성 은 자원 을 매우 소모 합 니 다.JVM 에 서 는 자바 문자열 을 저장 하기 위해 일부 공간 을 열 었 습 니 다.그것 이 바로 문자열 상수 풀 입 니 다.문자열 상수 탱크 를 통 해 두 내용 이 같은 문자열 변 수 는 탱크 에서 같은 문자열 대상 을 가리 키 며 관건 적 인 메모리 자원 을 절약 할 수 있 습 니 다
  • 스 레 드 보안:변경 할 수 없 는 문자열 은 자동 으로 스 레 드 안전 이 됩 니 다.여러 스 레 드 에서 접근 할 때 변경 되 지 않 기 때 문 입 니 다
  • hashcode 캐 시:문자열 도 해시 구현 에 광범 위 하 게 사용 되 고 있 습 니 다.예 를 들 어 HashMap,HashTable,HashSet 등 입 니 다.이 산열 을 조작 할 때 키 의 hashCode()방법 을 자주 호출 합 니 다.변경 할 수 없 는 문자열 의 값 이 변 하지 않 을 것 을 보장 합 니 다.따라서 hashCode()방법 은 String 클래스 에서 재 작성 되 어 캐 시 를 편리 하 게 합 니 다.이렇게 하면 첫 번 째 hashCode()호출 기간 에 캐 시 해시 와 계산 하고 그때 부터 같은 값 을 되 돌려 줍 니 다.
  • 3.면접 문제
    
    //       :       ;     ,    hello   
    String s = new String("hello");
    그렇다면 다음은 몇 개의 대상 이 생 성 될 까?
    
    //                 :helloworld。
    String s3 = "hello" + "world";
    
    이런 글자 의 양은'+'로 연결 되 고 컴 파일 러 는 컴 파일 기간 에 직접 최적화 된다.
    
    //      4   。2      :hello、world
    // 2    :StringBuilder、helloworld  
    String s = "hello";
    String s2 = s + "world";
    
    컴 파일 후,역 컴 파일 소프트웨어---jad 를 사용 하여 보기:
    
    String s1 = "hell0";
    String s2 = (new StringBuilder()).append(s1).append("world").toString();
    
    발견:"+"를 사용 하여 변수 와 글자 의 양 을 조합 한 결과 String 을 StringBuilder 로 변환 한 후 append()방법 으로 처 리 했 습 니 다.
    StringBuilder.toString()방법 원본 보기:
    
    @Override
    public String toString() {
    	// char[] value; value   StringBuilder       
        return new String(value, 0, count);
    }
    
    마지막 으로 toString()방법 을 호출 할 때 String 대상 을 만 듭 니 다.이 문자열 의 대상 은 더미 에 만 생 성 되 며 문자열 상수 탱크 에 만 생 성 되 지 않 습 니 다.따라서 4 개의 대상 을 만 듭 니 다(hello 와 World 는 문자열 상수 탱크 에서 직접 만 듭 니 다).
    자바.lang.string 류 를 깊이 이해 하 는 불변성 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바.lang.string 불변성 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기