programing

정수 불변

yoursource 2022. 9. 23. 22:05
반응형

정수 불변

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

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

(예상된) 결과 6을 제공하는 데 문제 없이 실행됩니다.즉, a의 값이 실질적으로 변화한 것입니다.그럼 Integer는 변형이 가능한 거 아닌가요?두 번째 질문으로 약간 엉뚱한 주제: "불변의 클래스에는 복사 컨스트럭터가 필요하지 않습니다."왜 그런지 설명해줄 사람?

이라고 해서 불변이라는 것은 a을 하다를 들어, 「」라고 하는 것은,String불변하지만 그래도 할 수 있어

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

str된 것이 '변경'입니다.str객체가 .Integer ,, 치의 a개체로 되었습니다. 즉연이이는없 did,,,,, did did did did did did did did did did did did did did did did did did did 。new Integer(6).

aInteger(3로, Integer(3)는 "Integer"(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()더은 플레인(plain)을 입니다.==, 값이 것이 것은 하지 않습니다).

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

'아이디'라는 '아이디를 볼 수 .a가 변경되었음을 나타냅니다.

첫 번째 질문에는

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

정수는 불변하기 때문에 위의 'a'가 값 6의 새로운 참조로 변경되었습니다.초기값 3은 메모리에 참조가 없는 상태로 유지되므로(변경되지 않음), 가비지 수집이 될 수 있습니다.

이 문제가 String에 발생할 경우 참조가 있을 것으로 예상되는 Integres보다 더 오랫동안 풀(PermGen 공간)에 유지됩니다.

Yes Integer는 불변입니다.

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

원래 개체를 수정하지 않고 다른 개체를 참조했습니다.

오브젝트와 참조의 차이에 대해서는, 여기를 참조해 주세요.

불변이라고 해서 변수의 값을 변경할 수 없는 것은 아닙니다.즉, 새로운 할당이 있으면 새로운 오브젝트가 생성되고(새로운 메모리 위치를 할당), 그 값이 할당됩니다.

이를 직접 이해하려면 루프 내에서 Integer 할당을 수행하고(루프 외부에서 정수가 선언됨) 메모리 내의 활성 개체를 확인합니다.

copy constructor가 불변의 객체에 필요하지 않은 이유는 단순한 상식입니다.각 할당은 새 개체를 생성하므로 언어에서 복사본을 이미 생성하므로 다른 복사본을 작성할 필요가 없습니다.

"불변의 클래스에는 복사 생성자가 필요하지 않습니다."왜 그런지 설명해줄 사람?

그 이유는 불변 클래스의 인스턴스를 복사할 필요가 거의 없기 때문입니다.오브젝트의 복사본은 원본과 "같은" 것이어야 하며, 동일한 경우 오브젝트를 작성할 필요가 없습니다.

단, 다음과 같은 기본적인 전제 조건이 있습니다.

  • 이 명령어는 응용 프로그램이 클래스 인스턴스의 개체 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

int가 변환될 수 있는 경우, "a"는 8을 인쇄하지만 불변하기 때문에 인쇄되지 않습니다.그 때문에 3이 됩니다.당신의 예는 단지 새로운 과제일 뿐입니다.

단순한 샘플 코드로 Integer(및 Float, Short 등 기타 신조)가 불변의 것임을 명확히 할 수 있습니다.

샘플 코드

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");
    }

}

실제 결과

결과는 예상된 결과가 아닌 Hi There 100으로 나타납니다(sb와 i가 모두 가변 객체인 경우). Hi There 1000

이는 i에 의해 작성된 오브젝트는 주로 수정되지 않은 반면 sb는 수정되었음을 나타냅니다.

따라서 String Builder는 Integer가 아닌 가변 동작을 시연했습니다.

그래서 정수는 불변이다.이 때문에 실증

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
}

출력은 다음과 같습니다.

안녕 1000 5000 5000 d a

따라서 char는 가변, String Integer 및 int는 불변입니다.

이 코드를 복사하여 실행합니다.이게 당신의 모든 의구심을 풀어주길 바랍니다.

private static void wrapperClassDemo() {
    //checking wrapper class immutability using valueOf method
    //We can create wrapper class by using either "new" keyword or using a static method "valueOf()"
    //The below Example clarifies the immutability concept of wrapper class in detail
    //For better understanding just ciopy the below code to the editor and run
        
    Integer num1 =Integer.valueOf(34);  // i'm passing the 34 as the parameter to the valueOf method
    System.out.println("value assigned to num1 is : "+num1);
    System.out.println("Printing the hashcode assigned to store the \" num1 \"value in memory: "+System.identityHashCode(num1));
        
    Integer num2 =Integer.valueOf(34);
    System.out.println("value assigned to num2 is : "+num2);
    System.out.println("Printing the hashcode assigned to store the \" num2 \"value in memory: "+System.identityHashCode(num2));
        
    /*Now u can notice both the hashcode value of num1 and num2 are same. that is because once you created the num1 with the value 34 an object is 
     * created in the heap memory. And now You are passing the value  same as num1 to the num2 .Now JVM Checks the same value is present in the heap Mmeomry
     * If present the reference variable(in this example it is num2) will  be pointed to the same address where the object num1 is stored so u get the same hashcode         */
         
        
    num2++; // You can use num2 = 35 as both are same; 
    System.out.println("\nvalue assigned to num2 is : "+num2);
    System.out.println("Printing the hashcode of  \" num1 \": "+System.identityHashCode(num1) + "\nPrinting the hashcode of  \" num2 \": "+System.identityHashCode(num2));
    System.out.println("As now you can notice the hashcode has changed for num2 ,That is because now a new object is created for num2 and it is referencing the new object");
        
    //Again i'm incrementing num2
    System.out.println("\nBefore incremeting  the hashcode of  \" num2 \" is: "+System.identityHashCode(num2));
    num2++; // You can use num2 = 36 as both are same;
    System.out.println("After incremeting  the hashcode of  \" num2 \" is: "+System.identityHashCode(num2));
    //now the hashcode value of num2 is changed ,again new object is created for the updated value and num2 is referencing new object ,and old object will be garbage collected
        
    System.out.println("\n Thus the CONCLUSION is Wrapper objects are immutable ,They only create new object and refernce the new object ,They won't modify the present object ");
    System.out.println("This is applicable for Strings also");

주의할 점은 Integer 값의 캐시가 있다는 것입니다.int에서 Integer로 변경할 때 .deloper() 대신 ==를 사용하는 실수로부터 개발자를 구하기도 합니다.하지만 항상 그렇지는 않다.새 Integer를 인스턴스화하면 새 인스턴스가 생성됩니다.정수는 불변할 뿐만 아니라 반정적인 것입니다.

    Integer a = 3;
    Integer b = 3;
    Integer c = new Integer(3);
    b = b + 1;
    b = b - 1;

    System.out.println("a-id: " + System.identityHashCode(a));
    System.out.println("b-id: " + System.identityHashCode(b));
    System.out.println("c-id: " + System.identityHashCode(c));
    System.out.println("a == b: " + (a == b));
    System.out.println("a == c: " + (a == c));
    System.out.println("a eq c: " + (a.equals(c)));    

인쇄물을 제공합니다.

a-id: 666988784
b-id: 666988784
c-id: 1414644648
a == b: 참
a == c: false
eq c: true

언급URL : https://stackoverflow.com/questions/5560176/is-integer-immutable

반응형