자바 의 불 가 변 클래스 와 String 의 불 가 변 메커니즘

4282 단어 Java
불가 변류의
가 변 하지 않 는 클래스 는 이러한 인 스 턴 스 를 만 든 후 이 인 스 턴 스 변 수 는 변경 할 수 없다 는 뜻 입 니 다.
자바 가 제공 하 는 8 개의 포장 류 와 자바. lang. string 류 는 모두 변 할 수 없 는 클래스 입 니 다. 인 스 턴 스 를 만 든 후 인 스 턴 스 변 수 는 변 할 수 없습니다.
사용자 정의 불 가 변 클래스 를 만 들 려 면 다음 규칙 을 만족 시 켜 야 합 니 다.
  • private 와 final 수식 자 를 사용 하여 이러한 구성원 변 수 를 수식 하고 클래스 가 계승 되 지 않도록 보증 합 니 다
  • 클래스 의 구성원 변수 에 만 getter 방법 을 제공 하고 setter 방법 을 제공 하지 않 습 니 다. getter 를 통 해 클래스 의 내부 가 변 적 인 구성원 대상 을 직접 조작 하여 구성원 변 수 를 변화 시 키 는 것 을 피하 기 위해 서 는 getter 방법 에서 대상 이 아 닌 복제 대상 을 되 돌려 주 고 대상 의 복사 본 을 되 돌려 야 합 니 다.
  • 필요 하 다 면 Object 류 의 equals () 방법 과 hashCode () 방법 을 다시 쓰 십시오.equals () 방법 은 관건 적 인 구성원 변수 에 따라 두 대상 이 동일 한 지 의 기준 으로 하고 그 밖 에 equals () 방법 으로 동일 한 대상 으로 판단 하 는 hashCode () 도 동일 하 다 는 것 을 보증 해 야 한다.
  • 매개 변 수 를 가 진 구조 기 를 제공 합 니 다. 들 어 오 는 매개 변수 에 따라 클래스 의 구성원 변 수 를 초기 화하 고 깊 은 복사 에 주의 하 십시오.public final class MyImmutableDemo {private final int [] myArray; public MyImmutableDemo (int [] array) {this. myArray = array. clone (); / / 오류 쓰기: this. myArray = array;}
  • 가 변 하지 않 는 클래스 를 설계 합 니 다. 특히 인용 유형의 구성원 변 수 를 주의해 야 합 니 다.인용 유형의 구성원 변수의 클래스 가 가 변 적 이 라면 이 구성원 변수 가 인용 한 대상 이 수정 되 지 않도록 필요 한 조 치 를 취해 야 진정한 가 변 클래스 를 만 들 수 있 습 니 다.
    String 대상 의 불변성
    string 대상 은 메모리 생 성 후 변경 할 수 없습니다. 변경 할 수 없 는 대상 의 생 성 은 일반적으로 상기 5 가지 원칙 을 만족 시 킵 니 다. String 코드 가 어떻게 실현 되 는 지 봅 시다.
    public final class String
        implements java.io.Serializable, Comparable, CharSequence
    {
        /** The value is used for character storage. */
        private final char value[];
        /** The offset is the first index of the storage that is used. */
        private final int offset;
        /** The count is the number of characters in the String. */
        private final int count;
        /** Cache the hash code for the string */
        private int hash; // Default to 0
        ....
        public String(char value[]) {
             this.value = Arrays.copyOf(value, value.length); // deep copy  
         }
        ...
         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;
        }
        ...
    }
    
  • String 클래스 는 final 로 수식 되 어 계승 불가
  • string 내부 의 모든 구성원 이 개인 변수 로 설정
  • value 가 존재 하지 않 는 setter
  • value 와 offset 을 final 로 설정 합 니 다.
  • 가 변 배열 value [] 에 들 어 갈 때 copy 를 진행 합 니 다. 내부 변수 에 직접 value [] 를 복사 하 는 것 이 아 닙 니 다.
  • value 를 가 져 올 때 대상 의 인용 을 직접 되 돌려 주 는 것 이 아니 라 대상 의 copy 를 되 돌려 줍 니 다.
  • String 대상 의 변 하지 않 는 장단 점
    이전 절 에서 분석 하면 String 데 이 터 는 가 변 류 가 아 닙 니 다. 그러면 이러한 특성 을 설정 하면 어떤 장점 이 있 습 니까?나 는 다음 과 같은 몇 가지 로 요약 한다.
  • 문자열 상수 탱크 의 필요 성. 문자열 상수 탱크 는 상수 탱크 에 일부 문자 상 수 를 두 고 반복 적 으로 사용 할 수 있 으 며 매번 같은 대상 을 다시 만 들 지 않 고 저장 공간 을 절약 할 수 있 습 니 다.그러나 문자열 이 가 변 적 이면 같은 내용 의 String 은 상수 탱크 의 같은 메모리 공간 을 가리 키 며, 어떤 변수 가 이 메모리 의 값 을 바 꾸 었 을 때 다른 옮 겨 다 니 는 값 도 변 경 됩 니 다.그래서 상수 탱크 디자인 의 취지 에 맞지 않 습 니 다.

  • 2. 라인 안전 고려.같은 문자열 인 스 턴 스 는 여러 스 레 드 에서 공유 할 수 있 습 니 다.이렇게 하면 스 레 드 안전 문제 로 동기 화 를 사용 하지 않 아 도 된다.문자열 자체 가 라인 이 안전 합 니 다.
  • 클래스 로 더 는 문자열 을 사용 해 야 합 니 다. 정확 한 클래스 를 불 러 올 수 있 도록 보안 을 제공 합 니 다.예 를 들 어 자바. sql. connection 류 를 불 러 오고 싶 은 데 이 값 이 my hacked. Connection 으로 바 뀌 면 데이터 베 이 스 를 알 수 없 는 파 괴 를 초래 할 수 있 습 니 다.
  • hash 맵 과 캐 시 를 지원 합 니 다.문자열 은 가 변 적 이지 않 기 때문에 만 들 때 hashcode 가 캐 시 되 어 다시 계산 할 필요 가 없습니다.이 때문에 문자열 은 Map 의 키 로 적합 하고 문자열 의 처리 속 도 는 다른 키 대상 보다 빠르다.이것 이 바로 HashMap 의 키 입 니 다. 문자열 을 자주 사용 합 니 다.

  • 주의해 야 할 것 은 String 대상 이 정말 가 변 적 이지 않 은 것 이 아니 라 우 리 는 반사 체 제 를 통 해 가 변 적 이지 않 은 대상 을 수정 할 수 있다 는 것 이다.코드 예 는 다음 과 같 습 니 다.
     //     "Hello World",      s
        String s = "Hello World"; 
        System.out.println("s = " + s); //Hello World
    
        //  String   value  
        Field valueFieldOfString = String.class.getDeclaredField("value");
        //  value       
        valueFieldOfString.setAccessible(true);
    
        //  s    value    
        char[] value = (char[]) valueFieldOfString.get(s);
        //  value         5   
        value[5] = '_';
        System.out.println("s = " + s);  //Hello_World
    

    출력: s = Hello World s = HelloWorld
    부분http://www.cnblogs.com/jaylon/p/5721571.html

    좋은 웹페이지 즐겨찾기