program story

정수 불변 임

inputbox 2020. 9. 1. 07:29
반응형

정수 불변 임


나는 이것이 아마도 매우 어리 석다는 것을 알고 있지만, 많은 곳에서 Java의 Integer 클래스가 불변이라고 주장하지만 다음 코드는 다음과 같습니다.

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

(예상 된) 결과를주는 데 아무런 문제없이 실행됩니다. 6. 따라서 a의 값이 효과적으로 변경되었습니다. 그것은 Integer가 변경 가능하다는 것을 의미하지 않습니까? 2 차 질문 및 약간의 주제를 벗어난 : "불변 클래스에는 복사 생성자가 필요하지 않습니다." 이유를 설명 해줄 사람이 있습니까?


불변성은 a결코 다른 값과 같을 수 없음을 의미하지 않습니다 . 예를 들어 String는 변경 불가능하지만 여전히이 작업을 수행 할 수 있습니다.

String str = "hello";
// str equals "hello"
str = str + "world";
// now str equals "helloworld"

str변경되지 않았습니다. 오히려 str이제 완전히 새로 인스턴스화 된 객체 Integer입니다. 따라서의 값은 a변경되지 않았지만 완전히 새로운 객체, 즉 new Integer(6).


aInteger (3)에 대한 "참조"입니다. 속기는 a+=b실제로 다음을 수행하는 것을 의미합니다.

a = new Integer(3 + 3)

따라서 정수는 변경할 수 없지만이를 가리키는 변수는 *입니다.

* 불변 변수를 가질 수 있습니다. 이러한 변수는 키워드로 표시되며 final참조가 변경되지 않을 수 있습니다.

final Integer a = 3;
final Integer b = 3;
a += b; // compile error, the variable `a` is immutable, too.

다음을 사용하여 객체가 변경되었는지 확인할 수 있습니다 System.identityHashCode()(더 나은 방법은 일반을 사용하는 ==것이지만 값이 아닌 참조가 변경된 것은 분명하지 않음).

Integer a = 3;
System.out.println("before a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
a += 3;
System.out.println("after a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));

인쇄물

before a +=3; a=3 id=70f9f9d8
after a +=3; a=6 id=2b820dda

참조하는 개체의 기본 "id" a가 변경되었음을 알 수 있습니다.


초기 질문에 대해

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

정수는 불변이므로 위에서 발생한 것은 'a'가 값 6의 새로운 참조로 변경된 것입니다. 초기 값 3은 메모리에 참조가없는 상태로 남아 있으므로 (변경되지 않음) 가비지 수집 될 수 있습니다.

이것이 문자열에 발생하면 참조를 가질 것으로 예상되는 정수보다 더 긴 기간 동안 풀 (PermGen 공간)에 보관됩니다.


예 Integer는 변경할 수 없습니다.

A는 객체를 가리키는 참조입니다. + = 3을 실행하면 A가 다른 값으로 새 Integer 개체를 참조하도록 다시 할당됩니다.

원래 개체를 수정 한 것이 아니라 다른 개체에 대한 참조를 가리 켰습니다.

여기 에서 객체와 참조의 차이점에 대해 읽어보십시오 .


불변성은 변수의 값을 변경할 수 없음을 의미하지 않습니다. 새로운 할당은 새로운 객체를 생성하고 (새 메모리 위치에 할당) 값이 할당된다는 것을 의미합니다.

이것을 직접 이해하려면 루프에서 정수 할당을 수행하고 (루프 외부에서 정수 선언 됨) 메모리에있는 라이브 객체를 살펴보십시오.

불변 객체에 복사 생성자가 필요하지 않은 이유는 단순한 상식입니다. 각 할당은 새 객체를 생성하므로 언어는 기술적으로 이미 사본을 생성하므로 다른 사본을 생성 할 필요가 없습니다.


"불변 클래스에는 복사 생성자가 필요하지 않습니다." 이유를 설명 해줄 사람이 있습니까?

그 이유는 변경 불가능한 클래스의 인스턴스를 복사 할 필요 거의 없기 때문입니다 . 개체의 복사본은 원본과 "동일"해야하며 동일하면 만들 필요가 없습니다.

하지만 몇 가지 기본 가정이 있습니다.

  • 응용 프로그램이 클래스 인스턴스의 개체 ID에 어떤 의미도 부여하지 않는다고 가정합니다.

  • 이 메서드에 따라 클래스가 오버로드 equals되어 hashCode인스턴스의 복사본이 원본과 "동일" 하다고 가정합니다 .

이러한 가정 중 하나 또는 둘 모두 가 거짓 일 있으며 복사 생성자를 추가해야합니다.


이것이 내가 불변을 이해하는 방법입니다

int a=3;    
int b=a;
b=b+5;
System.out.println(a); //this returns 3
System.out.println(b); //this returns 8

If int could mutate, "a" would print 8 but it does not because it is immutable, thats why it is 3. Your example is just a new assignment.


I can make clear that Integer (and other of its creed like Float, Short etc) are immutable by simple sample code:

Sample Code

public class Test{
    public static void main(String... args){
        Integer i = 100;
        StringBuilder sb = new StringBuilder("Hi");
        Test c = new Test();
        c.doInteger(i);
        c.doStringBuilder(sb);
        System.out.println(sb.append(i)); //Expected result if Integer is mutable is Hi there 1000
    }

    private void doInteger(Integer i){
        i=1000;
    }

    private void doStringBuilder(StringBuilder sb){
        sb.append(" there");
    }

}

Actual Result

The result comes to he Hi There 100 instead of expected result (in case of both sb and i being mutable objects) Hi There 1000

This shows the object created by i in main is not modified, whereas the sb is modified.

So StringBuilder demonstrated mutable behavior but not Integer.

So Integer is Immutable. Hence Proved

Another code without only Integer:

public class Test{
    public static void main(String... args){
        Integer i = 100;
        Test c = new Test();
        c.doInteger(i);
        System.out.println(i); //Expected result is 1000 in case Integer is mutable
    }

    private void doInteger(Integer i){
        i=1000;
    }


}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    String s1="Hi";
    String s2=s1;

    s1="Bye";

    System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
    System.out.println(s1); //Bye

    Integer i=1000;
    Integer i2=i;

    i=5000;

    System.out.println(i2); // 1000
    System.out.println(i); // 5000

    int j=1000;
    int j2=j;

    j=5000;

    System.out.println(j2); // 1000
    System.out.println(j); //  5000


    char c='a';
    char b=c;

    c='d';

    System.out.println(c); // d
    System.out.println(b); // a
}

Output is :

Hi Bye 1000 5000 1000 5000 d a

So char is mutable , String Integer and int are immutable.

참고URL : https://stackoverflow.com/questions/5560176/is-integer-immutable

반응형