JAVA 불변 인 클래스 불변성 (불변) 문자열 메커니즘

I. 서론 불변 인 클래스

불변 클래스 : 소위 불변 클래스는, 한 번 생성 된 클래스의 인스턴스를 참조 회원의 변수 값을 변경할 수 없습니다. Interger, 길고 문자열 : JDK에는 많은 불변 인 클래스 내부에서 온다.
가변 카테고리 : 불변 클래스에 대하여, 인스턴스 변수 반원 변수의 값을 변경할 수도 생성 개발은 대부분의 클래스는 클래스에 속하는 변수 생성한다.

불변 클래스의 두 번째 장점

그런 다음 클래스의 변수와 불변 인 클래스의 차이, 우리는 불변의 클래스가 있어야합니다 이유를 이해할 필요가? JAVA 혜택의 어떤 종류의 이러한 특성?

  1. 스레드 안전
    불변의 객체는 스레드 안전 및 개체의 값이 변경 될 수 없기 때문에, 동기화 문제를 보장하기 위해 특별한 메커니즘을 사용하지 않고, 서로의 스레드간에 공유 할 수 있습니다. 일부 잠금 장치는 메모리 일관성 문제도 동기화 오버 헤드를 줄일 수 있도록 더 사용하기 때문에 동시성 오류의 가능성을 줄일 수 있습니다.
  2. 쉬운 구성하기, 사용 및 테스트
  3. ...

불변 클래스의 셋째, 설계 방법

디자인 불변 클래스의 경우, 개인은 다음과 같은 원칙을 요약 :

1. 클래스가 상속되지 않도록, 최종 수정 클래스를 추가 .
클래스가 불변 메커니즘이 변수 값을 변경할 수 클래스,만큼 부모 클래스 상속 클래스 범위와 상속 클래스 멤버를 훼손 할 상속 될 수 있다면, 한 번 부모 클래스의 서브 클래스의 형태는 현재의 클래스 변수 여부를 보장 할 수 없습니다.

2. 모든 멤버 변수 개인해야합니다 있는지 확인하고 수정 된 최종 추가
하는 멤버 변수를 변경할 수 없습니다 보장하기 위해 이런 식으로. 하지만 객체가 외부 변화에 그 가치의 가능성을 가진 멤버 변수 인 경우 때문에이 단계는 충분하지 않습니다. 그래서 첫 번째 4:00이 결핍을 보충한다.

3.있어서 세터 포함한 멤버 변수 변화 제공하지 않는
멤버 변수의 값을 변경하는 다른 인터페이스에 의해 회피 손상 불변 특성.

4. 모든 초기화, 전체 복사 (깊은 복사)를 통해 회원

직접 멤버 변수에 할당 된 생성자 객체로 건네받는 경우에도 내부 변수의 값의 변화를 주도 들어오는 개체를 수정할 수 있습니다. 예를 들면 :

public final class ImmutableDemo {  
    private final int[] myArray;  
    public ImmutableDemo(int[] array) {  
        this.myArray = array; // wrong  
    }  
}

이와 같이 동일한 배열 불변성, myArray의 점을 보장 할 수없고, 메모리 어드레스는, 사용자 ImmutableDemo 외부 객체의 값을 수정하여 내부에서 myArray 배열의 값을 변경할 수있다.
변성되지 않은 내부 값을 보장하기 위해, 전달 깊이 값을 저장하기위한 새로운 메모리를 만드는 데 사용할 수 복사. 오른쪽 접근 방식 :

public final class MyImmutableDemo {  
    private final int[] myArray;  
    public MyImmutableDemo(int[] array) {  
        this.myArray = array.clone();   
    }   
}

5. 게터 처리는 직접적으로 객체 자체하지만 복제 객체를 리턴하고, 객체의 복사본을 반환하지 않는
이러한 접근하는 물체의 누출을 방지하고, 객체 멤버 변수 부재를 일으키는 내부 멤버 변수를 통해 게터 직접 조작을 방지하기 위해 얻어진다 변수는 변경된다.

String 객체의 넷째, 불변성

메모리에서 문자열 객체는 불변 생성 한 후, 불변의 객체의 다섯 개 가지 일반 원칙을 충족보다 더 만들고, 우리는 문자열 코드가 구현하는 방법을 참조하십시오.

public final class String
    implements java.io.Serializable, Comparable<String>, 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;
    }
    ...
}

코드에 나타낸 바와 같이, 다음과 같은 설계 세부 사항은 관찰 할 수있다 :

  1. String 클래스는 최종 변경, 상속 될 수 없습니다입니다
  2. 내부 문자열 변수의 모든 구성원은 비공개로 설정되어 있습니다
  3. 세터의 값이 존재하지 않습니다
  4. 그리고 가치와 최종으로 설정 오프셋.
  5. 복사 값 들어오는 변수 배열 값 []보다는 직접 []는 내부 변수로 복사하는 경우.
  6. 아니 직접 객체 참조 인수 값을 반환하지만 개체의 반환 사본.

이것은 또한 문자열 불변 클래스되도록, 상기 요약 특성의 동일한 유형에 부합된다.

String 객체의 장점과 단점 다섯째, 불변성

분석에서, 문자열 데이터는 좋은 것입니다 같은 기능을 제공하는 불변 클래스입니까? 나는 다음과 같이 요약 :

1. 문자열 상수 풀을 필요 .
문자열 상수 풀에 저장 공간을 절약하기 위해 다시 생성 할 때마다 동일한 개체 피하기 위해 재사용 상수 풀에 문자 상수의 일부가 될 수 있습니다. 문자열이 변수하지만,이 시간도 변수가 발생할, 통과 값이 변경의 다른 메모리의 값을 변경 동일한 메모리 공간의 동일한 콘텐츠 문자열 상수 풀을 가리 킵니다. 그래서 마음에 정수 풀 디자인을 충족하지 않습니다.

2. 스레드 안전 고려 사항 .
동일한 문자열의 예는 여러 스레드에 의해 공유 할 수 있습니다. 이 때문에 보안 스레드 동기화의 사용되지 않습니다. 자신의 문자열 스레드 안전합니다.

클래스 로더는 문자열을 사용하기 3. 올바른 클래스가로드되도록, 불변의 보안을 제공한다 . 예를 들어, java.sql.Connection의 클래스를로드 할,이 값이 myhacked.Connection을 변경, 그것은 불가지론 데이터베이스 손상의 원인이됩니다.

4. 지원 해시 매핑 및 캐싱.
문자열은 불변이므로,이 해시 코드 캐시를 만들 때, 다시 계산 할 필요가 없습니다 때문입니다. 이것은지도에서 키의 문자열로 적합한 문자열의 처리 속도가 다른 주요 개체를보다 빠르게 할 수 있습니다. 이것은 종종 HashMap의 문자열의 핵심입니다.

단점 :

  1. String 객체의 값의 변화에 ​​대한 요구가있는 경우, 그것은 문자열 많은 수의 개체를 생성합니다.

여섯째, 정말 불변의 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 = Hello_World

찾을 문자열이 변경되었습니다. 즉, 리플렉터는 소위 "불변"객체로 변형 될 수있다

개요

불변 클래스 인스턴스 생성이 통과 부재의 값 후 변경 될 수 없다. 이 기능은 각 속성이 다시 만들 새로운 객체에 인 변경, 불변 클래스는 스레드 안전 기능을 제공 할 수 있습니다뿐만 아니라 객체 생성의 비용을 제공합니다. JDK는 등 정수, 더블, 문자열, 많은 내부 불변 클래스를 제공한다 문자열 불변의 특성은 주로 상수 풀을 충족하기 위해, 스레드 안전은, 클래스 로더가 필요합니다. 불변 클래스의 합리적인 사용은 큰 혜택을 가져올 수 있습니다.

참고 자료

[1] http://my.oschina.net/zzw922cn/blog/487610

[2] 자바의 문자열 이유는 불변 : http://www.codeceo.com/article/why-java-string-immutable.html

[3] http://www.importnew.com/7535.html

원본 주소 : HTTPS : //www.cnblogs.com/jaylon/p/5721571.html

I. 서론 불변 인 클래스

불변 클래스 : 소위 불변 클래스는, 한 번 생성 된 클래스의 인스턴스를 참조 회원의 변수 값을 변경할 수 없습니다. Interger, 길고 문자열 : JDK에는 많은 불변 인 클래스 내부에서 온다.
가변 카테고리 : 불변 클래스에 대하여, 인스턴스 변수 반원 변수의 값을 변경할 수도 생성 개발은 대부분의 클래스는 클래스에 속하는 변수 생성한다.

불변 클래스의 두 번째 장점

그런 다음 클래스의 변수와 불변 인 클래스의 차이, 우리는 불변의 클래스가 있어야합니다 이유를 이해할 필요가? JAVA 혜택의 어떤 종류의 이러한 특성?

  1. 스레드 안전
    불변의 객체는 스레드 안전 및 개체의 값이 변경 될 수 없기 때문에, 동기화 문제를 보장하기 위해 특별한 메커니즘을 사용하지 않고, 서로의 스레드간에 공유 할 수 있습니다. 일부 잠금 장치는 메모리 일관성 문제도 동기화 오버 헤드를 줄일 수 있도록 더 사용하기 때문에 동시성 오류의 가능성을 줄일 수 있습니다.
  2. 쉬운 구성하기, 사용 및 테스트
  3. ...

불변 클래스의 셋째, 설계 방법

디자인 불변 클래스의 경우, 개인은 다음과 같은 원칙을 요약 :

1. 클래스가 상속되지 않도록, 최종 수정 클래스를 추가 .
클래스가 불변 메커니즘이 변수 값을 변경할 수 클래스,만큼 부모 클래스 상속 클래스 범위와 상속 클래스 멤버를 훼손 할 상속 될 수 있다면, 한 번 부모 클래스의 서브 클래스의 형태는 현재의 클래스 변수 여부를 보장 할 수 없습니다.

2. 모든 멤버 변수 개인해야합니다 있는지 확인하고 수정 된 최종 추가
하는 멤버 변수를 변경할 수 없습니다 보장하기 위해 이런 식으로. 하지만 객체가 외부 변화에 그 가치의 가능성을 가진 멤버 변수 인 경우 때문에이 단계는 충분하지 않습니다. 그래서 첫 번째 4:00이 결핍을 보충한다.

3.있어서 세터 포함한 멤버 변수 변화 제공하지 않는
멤버 변수의 값을 변경하는 다른 인터페이스에 의해 회피 손상 불변 특성.

4. 모든 초기화, 전체 복사 (깊은 복사)를 통해 회원

직접 멤버 변수에 할당 된 생성자 객체로 건네받는 경우에도 내부 변수의 값의 변화를 주도 들어오는 개체를 수정할 수 있습니다. 예를 들면 :

public final class ImmutableDemo {  
    private final int[] myArray;  
    public ImmutableDemo(int[] array) {  
        this.myArray = array; // wrong  
    }  
}

이와 같이 동일한 배열 불변성, myArray의 점을 보장 할 수없고, 메모리 어드레스는, 사용자 ImmutableDemo 외부 객체의 값을 수정하여 내부에서 myArray 배열의 값을 변경할 수있다.
변성되지 않은 내부 값을 보장하기 위해, 전달 깊이 값을 저장하기위한 새로운 메모리를 만드는 데 사용할 수 복사. 오른쪽 접근 방식 :

public final class MyImmutableDemo {  
    private final int[] myArray;  
    public MyImmutableDemo(int[] array) {  
        this.myArray = array.clone();   
    }   
}

5. 게터 처리는 직접적으로 객체 자체하지만 복제 객체를 리턴하고, 객체의 복사본을 반환하지 않는
이러한 접근하는 물체의 누출을 방지하고, 객체 멤버 변수 부재를 일으키는 내부 멤버 변수를 통해 게터 직접 조작을 방지하기 위해 얻어진다 변수는 변경된다.

String 객체의 넷째, 불변성

메모리에서 문자열 객체는 불변 생성 한 후, 불변의 객체의 다섯 개 가지 일반 원칙을 충족보다 더 만들고, 우리는 문자열 코드가 구현하는 방법을 참조하십시오.

public final class String
    implements java.io.Serializable, Comparable<String>, 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;
    }
    ...
}

코드에 나타낸 바와 같이, 다음과 같은 설계 세부 사항은 관찰 할 수있다 :

  1. String 클래스는 최종 변경, 상속 될 수 없습니다입니다
  2. 내부 문자열 변수의 모든 구성원은 비공개로 설정되어 있습니다
  3. 세터의 값이 존재하지 않습니다
  4. 그리고 가치와 최종으로 설정 오프셋.
  5. 복사 값 들어오는 변수 배열 값 []보다는 직접 []는 내부 변수로 복사하는 경우.
  6. 아니 직접 객체 참조 인수 값을 반환하지만 개체의 반환 사본.

이것은 또한 문자열 불변 클래스되도록, 상기 요약 특성의 동일한 유형에 부합된다.

String 객체의 장점과 단점 다섯째, 불변성

분석에서, 문자열 데이터는 좋은 것입니다 같은 기능을 제공하는 불변 클래스입니까? 나는 다음과 같이 요약 :

1. 문자열 상수 풀을 필요 .
문자열 상수 풀에 저장 공간을 절약하기 위해 다시 생성 할 때마다 동일한 개체 피하기 위해 재사용 상수 풀에 문자 상수의 일부가 될 수 있습니다. 문자열이 변수하지만,이 시간도 변수가 발생할, 통과 값이 변경의 다른 메모리의 값을 변경 동일한 메모리 공간의 동일한 콘텐츠 문자열 상수 풀을 가리 킵니다. 그래서 마음에 정수 풀 디자인을 충족하지 않습니다.

2. 스레드 안전 고려 사항 .
동일한 문자열의 예는 여러 스레드에 의해 공유 할 수 있습니다. 이 때문에 보안 스레드 동기화의 사용되지 않습니다. 자신의 문자열 스레드 안전합니다.

클래스 로더는 문자열을 사용하기 3. 올바른 클래스가로드되도록, 불변의 보안을 제공한다 . 예를 들어, java.sql.Connection의 클래스를로드 할,이 값이 myhacked.Connection을 변경, 그것은 불가지론 데이터베이스 손상의 원인이됩니다.

4. 지원 해시 매핑 및 캐싱.
문자열은 불변이므로,이 해시 코드 캐시를 만들 때, 다시 계산 할 필요가 없습니다 때문입니다. 이것은지도에서 키의 문자열로 적합한 문자열의 처리 속도가 다른 주요 개체를보다 빠르게 할 수 있습니다. 이것은 종종 HashMap의 문자열의 핵심입니다.

단점 :

  1. String 객체의 값의 변화에 ​​대한 요구가있는 경우, 그것은 문자열 많은 수의 개체를 생성합니다.

여섯째, 정말 불변의 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 = Hello_World

찾을 문자열이 변경되었습니다. 즉, 리플렉터는 소위 "불변"객체로 변형 될 수있다

개요

불변 클래스 인스턴스 생성이 통과 부재의 값 후 변경 될 수 없다. 이 기능은 각 속성이 다시 만들 새로운 객체에 인 변경, 불변 클래스는 스레드 안전 기능을 제공 할 수 있습니다뿐만 아니라 객체 생성의 비용을 제공합니다. JDK는 등 정수, 더블, 문자열, 많은 내부 불변 클래스를 제공한다 문자열 불변의 특성은 주로 상수 풀을 충족하기 위해, 스레드 안전은, 클래스 로더가 필요합니다. 불변 클래스의 합리적인 사용은 큰 혜택을 가져올 수 있습니다.

참고 자료

[1] http://my.oschina.net/zzw922cn/blog/487610

[2] 자바의 문자열 이유는 불변 : http://www.codeceo.com/article/why-java-string-immutable.html

[3] http://www.importnew.com/7535.html

원본 주소 : HTTPS : //www.cnblogs.com/jaylon/p/5721571.html

추천

출처www.cnblogs.com/jpfss/p/11527127.html