programing

문자열은 불변입니다.정확히 무슨 뜻이죠?

kingscode 2022. 8. 25. 22:06
반응형

문자열은 불변입니다.정확히 무슨 뜻이죠?

저는 불변의 스트링스에 다음과 같은 코드를 썼습니다.

public class ImmutableStrings {

    public static void main(String[] args) {
        testmethod();
    }

    private static void testmethod() {
        String a = "a";
        System.out.println("a 1-->" + a);
        a = "ty";
        System.out.println("a 2-->" + a);
    }
}

출력:

a 1-->a  
a 2-->ty

서 변수 값 " " " " "a(많은 사람들이 불변의 객체의 내용은 변경할 수 없다고 하지만)가 변경되었습니다.하지만 '불변'이라는 은 정확히 무슨 뜻일까?이 주제를 좀 더 명확히 해주시겠어요?

출처 : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

불변의 소동을 더 진행하기 전에, 먼저 다음 사항에 대해 살펴보겠습니다.String결론에 도달하기 전에 클래스 및 그 기능에 대해 설명합니다.

하면 됩니다.String 삭제:

String str = "knowledge";

하면 평상시와 로 이, 상, 음, 음, 음 등이 포함된 문자열이 됩니다."knowledge" '참고문헌'을 붙입니다.str 분히히간?간 단?? 그럼 다음 몇 기능을 해 보겠습니다.

 String s = str;     // assigns a new reference to the same string "knowledge"

다음 문장의 구조를 살펴보겠습니다.

  str = str.concat(" base");

에 문자열이 됩니다." base"로로 합니다.str어떻게 String체는는불?불 변??랍게,,,,그그그그그

은 VM의 합니다.String str discriptions."knowledge" 및가를 추가한다." base" 「」을 부여합니다"knowledge base" ㅇㅇ, ㅇㅇ, 이니까String이 값을 수 없습니다.str '새로'를 수 있습니다.String값, 값, 값 등을 합니다."knowledge base"할 수 있습니다.str.

이 말은 ,String오브젝트는 불변하지만 참조변수는 불변입니다.그래서 위의 예에서 참조가 새롭게 형성된 것을 언급하도록 만들어진 것입니다.String★★★★★★ 。

에서는 이 에서 두 가지 방법이 .String 값 " "로 첫: " " " " " ""knowledge"(이)가 있다s, "" " " " " " 입니다"knowledge base"(이)가 있다str엄밀히 말하면 3개의 지, 밀, 개, 개 3개의 .가 String은 문자 의 사물을 ."base" concat★★★★★★ 。

문자열 및 메모리 사용량에 관한 중요한 사실

에 또 참고 문헌이요?s로로 합니다."knowledge"는 그 린 that that that that that that that that that를 것이다String다만, 아직 존재하지만, 레퍼런스가 없기 때문에 분실된 것으로 간주됩니다.에 또 한 예를 들어볼까요?

String s1 = "java";
s1.concat(" rules");
System.out.println("s1 refers to "+s1);  // Yes, s1 still refers to "java"

현상:

  1. 번째 은 아주: .로운것것 것것작작String "java"를 참조해 주세요.s1그렇게.
  2. VM을 .String "java rules"그 어떤 것도 그것을 언급하지 않는다. 두 는요.String즉시 사라집니다.닿을 수가 없어요.

변수 " " "s1의 것을 .String "java".

모든.String를 만듭니다.String그럼이것들은 어디?String물체는?이것들은 메모리에 존재합니다.모든 프로그래밍 언어의 주요 목표하나는 메모리를 효율적으로 사용하는 것입니다.

애플리케이션이 성장함에 따라 리터럴이 메모리를 많이 차지하게 되어 용장성도 발생할 수 있습니다.따라서 Java를 보다 효율적으로 만들기 위해 JVM은 "String constant pool"이라고 불리는 메모리의 특별한 영역을 확보합니다.

가 「」를 .String 「」, 「」를 합니다.String하는 것이기존 리터럴로 전송됩니다.String 것은 String오브젝트가 생성됩니다.의 「」String을 사용하다여기서 만드는 요점은String변변: :

서서 String, "the constant pool",String오브젝트에 하나 또는 여러 개의 참조가 있을 수 있습니다.여러 개의 참조가 자신도 모르는 사이에 같은 값을 가리키고 있는 경우, 참조 중 하나가 해당 값을 수정하는 것은 좋지 않습니다. 그래서 사물은 불변의 존재입니다.

자, 이제 여러분은 이렇게 말할 수 있습니다. 만약 누군가가 수업의 기능을 무시한다면요?그렇기 때문에 아무도 메서드의 동작을 덮어쓸 수 없도록 클래스가 표시됩니다.

문자열은 개체 자체는 변경할 수 없지만 개체에 대한 참조는 변경할 수 있음을 의미합니다.

「 」를 실행하는 a = "ty" '아까부터'의 참조를 바꾸고 a 리터럴 스트링에 합니다."ty".

오브젝트 변경이란 예를 들어 메서드를 사용하여 필드 중 하나를 변경하는 것을 의미합니다(또는 필드는 퍼블릭이며 최종 필드가 아니므로 메서드를 통해 액세스하지 않고 외부에서 업데이트할 수 있습니다).

Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"

예를 들어 String과 같은 불변 클래스(상속에 의한 변경을 방지하기 위해 final로 선언됨)에서는(메서드는 필드를 변경할 수 없으며 필드는 항상 비공개이며 final이 권장됨) 현재 String은 변경할 수 없지만 새로운 String을 반환할 수 있습니다.

String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"

바꿀 거예요?a 를 참조합니다.이것을 시험해 보세요.

String a="a";
System.out.println("a 1-->"+a);
String b=a;
a="ty";
System.out.println("a 2-->"+a);
System.out.println("b  -->"+b);

이제 알 수 있습니다.a 다음에 또 한 번.b이치노

가 하지 않도록 a 해 보다, 라고.

final String a="a";

은 「」입니다.char[]일련의 UTF-16 코드 유닛을 포함한int하고, 「」를 붙입니다.int★★★★★★ 。

예를들면.

String s

문자열 참조를 위한 공간을 만듭니다.복사본을 할당하면 참조가 주위에 할당되지만 참조가 참조되는 개체는 수정되지 않습니다.

또, 다음의 점에 주의해 주세요.

new String(s)

이것 같은 배열 오프셋, 되는 다른 입니다.s이렇게 하는 이유는 매우 드물기 때문에 대부분의 Java 프로그래머들은 이를 나쁜 관행으로 간주합니다.

는 Java와 같이 로 묶습니다."my string"실제로 인턴십에 대한 언급입니다. String"bar"는 코드에 표시되는 횟수에 관계없이 동일한 String 인스턴스를 참조하는 것입니다.


hello "hello"는 1개의 인스턴스를 .new String(...)는 비실행 인스턴스를 만듭니다.★★를 해 보세요.System.out.println(("hello" == "hello") + "," + (new String("hello") == "hello") + "," + (new String("hello") == new String("hello")));그리고 당신은 봐야 한다true,false,false

unfound는 동일한 참조의 값을 변경할 수 없음을 의미합니다.새로운 참조를 작성하기 위해 필요할 때마다 새로운 메모리 위치를 의미합니다.예:

String str="abc";
str="bcd";

여기, 위의 코드, 메모리에는 값을 저장하기 위한 2개의 블록이 있습니다.첫 번째 값은 "bcd" 값이고 두 번째 값은 "bcd" 값입니다.두 번째 값은 첫 번째 값으로 대체되지 않습니다.

이것은 불변의 존재라고 불린다.

예에서는 " " " " 가 사용됩니다.a는 문자열 객체의 인스턴스에 대한 참조일 뿐입니다.라고 말할 때a = "ty"문자열 오브젝트를 실제로 변경하는 것이 아니라 완전히 다른 문자열 클래스의 인스턴스를 참조합니다.

여기를 참조해 주세요.

class ImmutableStrings {

    public static void main(String[] args) {
        testmethod();
    }

    private static void testmethod() {
    String a="a";
    System.out.println("a 1-->"+a);
    System.out.println("a 1 address-->"+a.hashCode());

    a = "ty";
    System.out.println("a 2-->"+a);

       System.out.println("a 2 address-->"+a.hashCode());
    }
}

출력:

a 1-->a
a 1 address-->97
a 2-->ty
a 2 address-->3717

객체의 마다 항상 변경됨을 .a사물의 할 수 주소가 서로 다른 거예요이치

할당문의 개체를 변경하는 것이 아니라 하나의 불변 개체를 다른 개체로 바꿉니다.물건String("a")는 변하지 .String("ty")폐기되고 에 대한 참조가 표시됩니다.ty a그 대신에.

그에 반해서,StringBuffer가변 객체를 나타냅니다.다음과 같이 할 수 있습니다.

StringBuffer b = new StringBuffer("Hello");
System.out.writeln(b);
b.append(", world!");
System.out.writeln(b);

.b: 같은 개체를 가리키지만 해당 개체의 내용이 변경되었습니다.

실제로 새 문자열에 대한 참조를 가져오고 있습니다. 문자열 자체는 변경되지 않으므로 변경되지 않습니다.이것은 관련이 있다.

Wikipedia에서 불변의 객체

불변 객체는 생성된 후 상태를 수정할 수 없는 객체입니다.

★★★★★★★★★★★★★★★★★.a = "ABC"<--불변의 오브젝트."a"는 객체를 참조합니다.ㅇㅇㅇㅇㅇ.a = "DEF"<--또 다른 불변의 오브젝트 "a"는 현재 그 오브젝트를 참조하고 있습니다.

문자열 개체를 할당하면 해당 개체를 메모리에서 변경할 수 없습니다.

요약하면 "a"의 참조를 새 문자열 개체로 변경한 것입니다.

String S1="abc";
S1.concat("xyz");
System.out.println("S1 is", + S1);
String S2=S1.concat("def");
System.out.println("S2 is", + S2);

이것은 문자열 오브젝트가 일단 생성되면 변경할 수 없음을 나타냅니다.EveryTime을 새로 생성하여 다른 String을 추가해야 합니다.s

다음 코드가 차이를 해소한다고 생각합니다.

String A = new String("Venugopal");
String B = A;

A = A +"mitul";

System.out.println("A is " + A);
System.out.println("B is " + B);

StringBuffer SA = new StringBuffer("Venugopal");
StringBuffer SB = SA;

SA = SA.append("mitul");

System.out.println("SA is " + SA);
System.out.println("SB is " + SB);

String 불변, 불변, 불변, 불변, 불변, 불변, 불변.String값을 오브젝트 형식으로 저장합니다.그래서 만약 당신이 그 값을 할당한다면String a="a";되고 값이 됩니다.a="ty".명확하게 이해하려면 , 다음의 항목을 체크해 주세요.has code★★★★★★★★★★★★★★★★의 경우String.

참조만 변경됩니다. 번째 번째a문자열 "a"를 참조하다가 나중에 "ty"로 변경했습니다.

예에서는 " " 입니다.a"a" 이어 에, 에, 에"ty"은 어떤 변환도 하지 String" " " " " " " " " " " " " " " " " 를 합니다.String 「」a를 참조합니다.예를 들어 다음과 같습니다.

String a = "a";
String b = a; // b refers to the same String as a
a = "b"; // a now refers to a different instance
System.out.println(b);

는 'a'로 합니다. 'a'는 'a'가 변이되지 않기 때문입니다.왜냐하면 우리는 절대 변환하지 않기 때문입니다.String「」b가리키고 있습니다.

오브젝트 「」가 경우bar 、 object object object object holds holds holds holds객체에 대한 .foo 스테이트의 일부를 의 스테이트의 가변적인 측면에 캡슐화해, 이러한 측면을 변경할 수 있는 코드를 가능하게 합니다.foobar실제로 만지거나 존재조차 모르는 상태.일반적으로 이것은 변환 가능한 개체를 사용하여 자신의 상태를 캡슐화하는 개체는 이러한 개체에 대한 참조가 예기치 않게 변환될 수 있는 코드에 노출되지 않도록 해야 함을 의미합니다.대조적으로, 만약bar에 .moo만을 사용합니다.moo 상태를 캡슐화하는 ID 이외의 경우, 그 상태를 캡슐화합니다.bar할 수 moo외부 코드의 영향을 걱정할 필요 없이 외부 코드로 이동할 수 있습니다.

아래 코드가 당신의 의심을 풀어주기를 바랍니다.

public static void testString() {
    String str = "Hello";
    System.out.println("Before String Concat: "+str);
    str.concat("World");
    System.out.println("After String Concat: "+str);
    StringBuffer sb = new StringBuffer("Hello");
    System.out.println("Before StringBuffer Append: "+sb);
    sb.append("World");
    System.out.println("After StringBuffer Append: "+sb);
}

String Concat (': ')
String Concat ": "
String Buffer " " : "
String Buffer " : HelloWorld " "

위에 , 제은 '아까부터' '아까부터' '아까부터' '아까부터' '아까부터' '아까부터' '아까부터'를 입니다.hashCode() 한번할 수 위치에 .생성된 값은 수정할 수 없으며 수정하면 다른 메모리 위치에 새 값이 생성됩니다.

public class ImmutabilityTest {

    private String changingRef = "TEST_STRING";

    public static void main(String a[]) {

        ImmutabilityTest dn = new ImmutabilityTest();

        System.out.println("ChangingRef for TEST_STRING OLD : "
                + dn.changingRef.hashCode());

        dn.changingRef = "NEW_TEST_STRING";
        System.out.println("ChangingRef for NEW_TEST_STRING : "
                + dn.changingRef.hashCode());

        dn.changingRef = "TEST_STRING";
        System.out.println("ChangingRef for TEST_STRING BACK : "
                + dn.changingRef.hashCode());

        dn.changingRef = "NEW_TEST_STRING";
        System.out.println("ChangingRef for NEW_TEST_STRING BACK : "
                + dn.changingRef.hashCode());

        String str = new String("STRING1");
        System.out.println("String Class STRING1 : " + str.hashCode());

        str = new String("STRING2");
        System.out.println("String Class STRING2 : " + str.hashCode());

        str = new String("STRING1");
        System.out.println("String Class STRING1 BACK : " + str.hashCode());

        str = new String("STRING2");
        System.out.println("String Class STRING2 BACK : " + str.hashCode());

    }
}

산출량

ChangingRef for TEST_STRING OLD : 247540830
ChangingRef for NEW_TEST_STRING : 970356767
ChangingRef for TEST_STRING BACK : 247540830
ChangingRef for NEW_TEST_STRING BACK : 970356767
String Class STRING1 : -1163776448
String Class STRING2 : -1163776447
String Class STRING1 BACK : -1163776448
String Class STRING2 BACK : -1163776447

String은 불변입니다.String 객체의 내용은 일단 생성되면 변경할 수 없습니다.내용을 변경할 경우 String 대신 StringBuffer/StringBuilder를 사용할 수 있습니다.StringBuffer 및 StringBuilder는 가변 클래스입니다.

언급URL : https://stackoverflow.com/questions/8798403/string-is-immutable-what-exactly-is-the-meaning

반응형