Java에서 문자열의 불변성


218

다음 예를 고려하십시오.

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

이제 Java에서 String 객체는 변경할 수 없습니다. 그런 다음 개체에 어떻게 str"도움말!"값을 할당 할 수 있습니까? 이것이 Java에서 문자열의 불변성과 모순되지 않습니까? 아무도 불변성의 정확한 개념을 설명해 주시겠습니까?

편집하다:

확인. 나는 지금 그것을 받고 있지만 하나의 후속 질문입니다. 다음 코드는 어떻습니까?

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

이것은 두 개의 객체 ( "Mississippi"와 "M! ss! ss! pp!")가 다시 생성되고 참조가 방법 str후에 다른 객체를 가리키는 것을 의미 replace()합니까?


STR은 참조 만 자체를 반대하지입니다
ahmednabil88

답변:


316

str객체가 아니라 객체에 대한 참조입니다. "Hello"그리고 "Help!"두 개의 구별되는 String객체. 따라서 문자열을 str 가리 킵니다 . 당신은 무엇을 변경할 수 있습니다 가리키는 것이 아니라 어떤 것을 가리키고있다 .

이 코드를 예로 들어 보겠습니다.

String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"

이제 아무것도 없다 에 우리가 할 수있는 s1그 값에 영향을 미칠 것입니다 s2. 그것들은 같은 객체 (문자열)를 참조 "Hello"하지만 그 객체는 불변이므로 변경할 수 없습니다.

우리가 이런 식으로하면 :

s1 = "Help!";
System.out.println(s2); // still prints "Hello"

여기에서 객체를 변경하고 참조를 변경하는 것의 차이점을 볼 수 있습니다. s2여전히 초기에 설정 한 것과 동일한 객체 s1를 가리 킵니다. 설정 s1"Help!"단지 변경하는 것은 참조 그동안, String원래 그대로 남아 지칭 개체.

문자열 변경 가능하면 다음과 같이 할 수 있습니다.

String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"

OP의 편집에 응답하도록 편집 :

String.replace (char, char)소스 코드를 살펴보면 ( JDK 설치 디렉토리의 src.zip에서도 사용 가능) 실제로 어떻게 작동하는지 궁금 할 때마다 살펴 보는 것이 좋습니다. 다음과 같습니다.

  • oldChar현재 문자열에 하나 이상의 발생이 있는 경우 모든 발생이 oldChar로 대체 되는 현재 문자열의 사본을 작성하십시오 newChar.
  • (가) 경우 oldChar현재 문자열에 존재하지 않는, 현재의 문자열을 반환합니다.

예, "Mississippi".replace('i', '!')String객체를 만듭니다 . 다시 말하지만 다음과 같습니다.

String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects

지금 당신의 숙제는 위의 코드가 변경 않을 경우 무엇을 보는 것입니다 s1 = s1.replace('i', '!');s1 = s1.replace('Q', '!');:)


1 실제로 문자열 (및 기타 불변 객체)을 변경 하는 것이 가능합니다. 리플렉션이 필요하고 매우 위험하며 프로그램을 실제로 파기하지 않는 한 절대 사용해서는 안됩니다.


15
가상 방법의 경우 +1은 불변 객체와 다른 객체의 차이점을 보여줍니다.
Zappi

1
올바른 예제와 명확한 설명에 대해 gustafc에게 감사드립니다 ....하지만 질문의 편집 된 부분에 답할 수 있습니까? 그것은 나의 이해를 분명히 할 것입니다.
Light_handle

17
나는 전에 이와 같은 대답을 본 적이 없다. 모든 세부 사항을 논의했습니다.
Michael 'Maik'Ardan

+1 여기에 자바의 불변 객체는 값으로 복사하는 것과 같으며, 문자열에 대한 2 개의 참조를 가질 수 있지만 불변이기 때문에 2 개의 별도의 문자열을 고려해야하며 그중 하나를 사용하면 영향을 미치지 않습니다. 기타
Khaled.K

1
자바-당신이 더 많이 알고 있다고 생각할수록 실제로 알지 못한다.
zeeshan

23

str참조 하는 객체 는 변경 될 수 있지만 실제 String객체 자체는 변경할 수 없습니다.

String문자열을 포함하는 객체 "Hello""Help!"따라서 그들은 불변하기 때문에, 그 값을 변경할 수 없다.

String객체 의 불변성이 객체를 가리키는 참조가 변경 될 수 없음을 의미하지는 않습니다.

str참조가 변경되는 것을 막을 수있는 한 가지 방법은 다음과 같이 선언하는 것입니다 final.

final String STR = "Hello";

이제 또 다른를 할당하려고 String하는 STR컴파일 오류가 발생합니다.


그러나이 경우 String 객체는 'str'이며, 먼저 'Hello'값을 포함하고 새로운 값 'Help!'가 할당됩니다. "문자열"Hello "및"Help! "를 포함하는 문자열 개체는 값을 변경할 수 없으므로 변경할 수 없습니다."라는 의미는 무엇입니까? 이것이 바보 같은 질문이라면 용서하십시오. 그러나 IV는 ...을 취소있어
Light_handle

2
C로 프로그래밍하려고 시도한 모든 사람들에게 perchance가 있습니까? 포인터로 입문서를 읽으면 coobird의 답변을 완벽하게 이해할 수 있습니다.
Ryan Fernandes

... 이것은 내가 피하고 싶은 것입니다 ... 나는 당신이 훌륭한 프로그래머라는 것을 알고 있습니다 ... 그리고 나는 여기서 Java를 배우려고 노력하고 있습니다 ... 그래서 내 질문에 올바르게 대답 할 수 있다면 대답하십시오. .
Light_handle

참조와 개체를 혼동하고 있습니다 str. "개체"가 아니라 개체에 대한 참조입니다. 당신이 경우 String str = "Hello";다음 String anotherReference = str;이 String 객체가없는 당신, 당신은 하나의 객체 그 (에 (문자 그대로 "안녕하세요") 및 2 참조가 stranotherReference).
Nate

편집 할 권한은 없지만, 그렇게하면 coobirds 첫 번째 문장을 편집합니다. "str 참조는 변경 될 수 있지만 실제 문자열 개체 자체는 변경할 수 없습니다."
j3App

10

Light_handle 변수Pass-by-Value Please (컵 크기 계속)에 대한 이야기컵 크기를 읽는 것이 좋습니다 . 위의 게시물을 읽을 때 많은 도움이 될 것입니다.

읽어 보셨습니까? 예. 좋은.

String str = new String();

""라는 새로운 "원격 제어"를 작성하고이를 strnew String()(또는 "")으로 설정합니다.

예를 들어 메모리에서 다음을 생성합니다.

str --- > ""

str  = "Hello";

그러면 리모콘 " str" 이 변경 되지만 원래 문자열은 수정되지 않습니다 "".

예를 들어 메모리에서 다음을 생성합니다.

str -+   ""
     +-> "Hello"

str = "Help!";

그러면 리모컨 " str"이 (가) 변경되지만 원래 문자열 ""이나 리모컨이 현재 가리키는 객체는 수정되지 않습니다 .

예를 들어 메모리에서 다음을 생성합니다.

str -+   ""
     |   "Hello"
     +-> "Help!"

""및 "Hello"는 가비지 수집을 수행합니까?
Prabin Timsina 2019

@PrabinTimsina 이것은 정말로 새로운 질문이어야합니다. 답변 : stackoverflow.com/questions/15324143/…
Michael Lloyd Lee mlk

9

몇 부분으로 나눕니다

String s1 = "hello";

이 문장은 메모리에 Hello 공간과 점유 공간을 포함하는 문자열 , 즉 상수 문자열 풀 을 생성하고이를 참조 객체 s1에 할당합니다.

String s2 = s1;

이 문장은 같은 문자열 hello 를 새로운 참조 s2에 할당합니다.

         __________
        |          |
s1 ---->|  hello   |<----- s2
        |__________| 

두 참조 모두 동일한 문자열을 가리 키므로 다음과 같은 값을 출력하십시오.

out.println(s1);    // o/p: hello
out.println(s2);    // o/p: hello

문자열변경할 수 없지만 할당이 가능하므로 s1 은 이제 새로운 값 스택을 참조합니다 .

s1 = "stack";    
         __________
        |          |
s1 ---->|  stack   |
        |__________|

그러나 안녕하세요를 가리키는 s2 객체는 어떻 습니까 ?

         __________
        |          |
s2 ---->|  hello   |
        |__________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello

String은 불변이므로 Java Virtual Machine은 메소드로 문자열 s1을 수정할 수 없습니다 . 다음과 같이 풀에 모든 새 문자열 객체를 만듭니다.

s1.concat(" overflow");

                 ___________________
                |                   |
s1.concat ----> |  stack overflow   |
                |___________________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello
out.println(s1.concat); // o/p: stack overflow

문자열이 변경 가능하면 출력은

out.println(s1);    // o/p: stack overflow

이제 String에 concat () 과 같은 메소드 를 수정 한 이유가 놀랍습니다 . 스 니펫을 따르면 혼란이 사라집니다.

s1 = s1.concat(" overflow");

여기에서는 수정 된 문자열 값을 다시 s1 참조에 할당 합니다.

         ___________________
        |                   |
s1 ---->|  stack overflow   |
        |___________________|


out.println(s1);    // o/p: stack overflow
out.println(s2);    // o/p: hello

그래서 Java는 String을 최종 클래스 로 결정했습니다. 그렇지 않으면 누구나 문자열 값을 수정하고 변경할 수 있습니다. 이것이 조금 도움이되기를 바랍니다.


6

처음 참조한 문자열 객체는 str변경되지 않았으므로 str새 문자열 객체를 참조하기 만하면됩니다.


5

문자열은 변경되지 않으며 참조는 변경됩니다. 불변성과 final필드 개념을 혼동하고 있습니다. 필드가로 선언되면 final, 일단 할당 된 필드는 재 할당 할 수 없습니다.


5

질문의 교체 부분과 관련하여 다음을 시도하십시오.

String str = "Mississippi"; 
System.out.println(str); //Prints Mississippi 

String other = str.replace("i", "!"); 
System.out.println(str); //still prints Mississippi 
System.out.println(other);  // prints M!ss!ss!pp!

4

자바는 그것을 무시하려고 노력하지만 str포인터에 지나지 않습니다. 즉 str = "Hello";, 처음 쓸 때는 str가리키는 객체를 만듭니다 . str을 써서 재 할당 str = "Help!";하면 새로운 객체가 생성되고 "Hello"Java가 느껴질 때마다 오래된 객체가 가비지 수집됩니다.


3

불변성은 인스턴스화 된 객체의 값을 변경할 수 없다는 것을 의미합니다. "Hello"를 "Help!"로 바꿀 수 없습니다.

변수 str은 객체에 대한 참조이며, str에 새 값을 할당하면 참조하는 객체의 값을 변경하지 않고 다른 객체를 참조하게됩니다.


3

문자열 클래스는 변경할 수 없으며 변경할 수없는 객체의 값을 변경할 수 없습니다. 그러나 문자열의 경우 문자열 값을 변경하면 문자열 풀에 새 문자열이 생성되고 문자열 참조보다 이전 값이 아닌 해당 값에 대한 문자열 참조가 생성됩니다. 이런 식으로 문자열은 변경할 수 없습니다. 예를 들어 보자.

String str = "Mississippi";  
System.out.println(str); // prints Mississippi 

하나의 문자열 "Mississippi" 를 생성 하고 문자열 풀에 추가하여 str이 미시시피를 가리 키도록합니다.

str = str.replace("i", "!");  
System.out.println(str); // prints M!ss!ss!pp! 

그러나 위의 작업 후에 다른 문자열 "M! ss! ss! pp!"가 만들어집니다. 문자열 풀에 추가됩니다. 그리고 str은 미시시피가 아닌 M! ss! ss! pp!를 가리키고 있습니다.

따라서이 방법으로 문자열 객체의 값을 변경하면 객체가 하나 더 생성되어 문자열 풀에 추가됩니다.

하나 더 예를 들어 보자

String s1 = "Hello"; 
String s2 = "World"; 
String s = s1 + s2;

이 세 줄 위의 문자열 풀에 세 개의 문자열 개체를 추가합니다.
1) Hello
2) World
3) HelloWorld


2

사용하다:

String s = new String("New String");
s.concat(" Added String");
System.out.println("String reference -----> "+s); // Output: String reference -----> New String

여기에서 볼 때 concat메서드를 사용하여 원래 문자열, 즉 "Add String"이라는 문자열을 가진 "New String"을 변경하지만 여전히 이전과 같이 출력을 얻었으므로 객체의 참조를 변경할 수 없음을 증명합니다 String 클래스의,하지만 StringBuilder 클래스 로이 작업을 수행하면 작동합니다. 아래에 나와 있습니다.

StringBuilder sb = new StringBuilder("New String");
sb.append(" Added String");
System.out.println("StringBuilder reference -----> "+sb);// Output: StringBuilder reference -----> New String Added String

2

Linus Tolvards가 말한 것처럼 :

대화는 싸다. 코드를 보여줘

이것 좀 봐 :

public class Test{
    public static void main(String[] args){

        String a = "Mississippi";
        String b = "Mississippi";//String immutable property (same chars sequence), then same object

        String c = a.replace('i','I').replace('I','i');//This method creates a new String, then new object
        String d = b.replace('i','I').replace('I','i');//At this moment we have 3 String objects, a/b, c and d

        String e = a.replace('i','i');//If the arguments are the same, the object is not affected, then returns same object

        System.out.println( "a==b? " + (a==b) ); // Prints true, they are pointing to the same String object

        System.out.println( "a: " + a );
        System.out.println( "b: " + b );

        System.out.println( "c==d? " + (c==d) ); // Prints false, a new object was created on each one

        System.out.println( "c: " + c ); // Even the sequence of chars are the same, the object is different
        System.out.println( "d: " + d );

        System.out.println( "a==e? " + (a==e) ); // Same object, immutable property
    }
}

출력은

a==b? true
a: Mississippi
b: Mississippi
c==d? false
c: Mississippi
d: Mississippi
a==e? true

따라서 두 가지를 기억하십시오.

  • 문자열은 조작하고 새로운 것을 생성하는 메소드를 적용 할 때까지 (c & d 경우) 변경할 수 없습니다.
  • 두 매개 변수가 모두 같은 경우 Replace 메서드는 동일한 String 객체를 반환합니다.

0

자바에서 문자열 불변성을 깨는 방법을 궁금해하는 사람들을 위해 ...

암호

import java.lang.reflect.Field;

public class StringImmutability {
    public static void main(String[] args) {
        String str1 = "I am immutable";
        String str2 = str1;

        try {
            Class str1Class = str1.getClass();
            Field str1Field = str1Class.getDeclaredField("value");

            str1Field.setAccessible(true);
            char[] valueChars = (char[]) str1Field.get(str1);

            valueChars[5] = ' ';
            valueChars[6] = ' ';

            System.out.println(str1 == str2);
            System.out.println(str1);
            System.out.println(str2);           
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

산출

true
I am   mutable
I am   mutable

0

문자열변경할 수 없습니다 . 따라서 참조 만 변경할 수 있습니다 .


String a = "a";
System.out.println("String a is referencing to "+a); // Output: a

a.concat("b");
System.out.println("String a is referencing to "+a); // Output: a

a = a.concat("b");
System.out.println("String a has created a new reference and is now referencing to "+a); // Output: ab

0

Java에서 객체는 일반적으로 참조로 액세스됩니다. 코드에서 str은 먼저 "Hello"(자동 생성 된 객체 또는 상수 풀 에서 가져온 )에 할당 된 다음 다른 객체 "Help!"를 할당 한 참조입니다. 동일한 참조로. 주목할 점은 참조가 동일하고 수정되었지만 개체가 다르다는 것입니다. 코드에서 한 가지 더, 세 개의 객체에 액세스했습니다.

  1. new String ()을 호출했을 때
  2. "hello"를 할당 한 경우
  3. "도움말!"을 할당 할 때

new String ()을 호출하면 문자열 풀에 존재하더라도 새 객체가 만들어 지므로 일반적으로 사용해서는 안됩니다. new String ()에서 만든 문자열을 문자열 풀에 넣으려면 intern()메서드를 사용해보십시오 .

이게 도움이 되길 바란다.


0

내가 말할 수없는 불변성은 문자열 자체를 변경할 수 없다는 것입니다. "abc"값인 String x가 있다고 가정합니다. 이제 문자열을 변경할 수 없습니다. 즉, "abc"에서 문자를 변경할 수 없습니다.

String에서 문자를 변경해야하는 경우 문자 배열을 사용하여 변경하거나 StringBuilder를 사용할 수 있습니다.

String x = "abc";
x = "pot";
x = x + "hj";
x = x.substring(3);
System.out.println(x);

char x1[] = x.toCharArray();
x1[0] = 's';
String y = new String(x1);
System.out.println(y);

산출:

hj
sj

0

또는 시도해 볼 수 있습니다.

public class Tester
{
public static void main(String[] args)
{
 String str = "Mississippi"; 
 System.out.println(str); // prints Mississippi 
 System.out.println(str.hashCode());

 str = str.replace("i", "!"); 
 System.out.println(str); // prints M!ss!ss!pp! 
 System.out.println(str.hashCode());
 }
 }

해시 코드가 어떻게 변하는 지 보여줍니다.


0

문자열은 변경할 수 없으므로 개체 자체는 변경할 수 없지만 개체에 대한 참조는 변경할 수 있습니다. 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과 같이 현재 문자열을 변경할 수는 없지만 새로운 문자열을 반환 할 수 있습니다.

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"

0

여기서 불변성은 인스턴스가 다른 참조를 가리킬 수 있지만 문자열의 원래 내용은 원래 참조에서 수정되지 않음을 의미합니다. 당신이 제시 한 첫 번째 예를 들어 설명하겠습니다. 첫 번째 str은 "Hello"를 가리키고 있습니다. 두 번째로 "도움말!"을 가리 킵니다. 여기 str은 "도움말!"을 가리 키기 시작했습니다. "Hello"문자열의 참조가 손실되어 다시 되돌릴 수 없습니다.

실제로 str이 기존 내용을 수정하려고하면 다른 새 문자열이 생성되고 str이 해당 참조를 가리 키기 시작합니다. 따라서 원래 참조의 문자열은 수정되지 않지만 참조에서 안전하고 객체의 인스턴스가 다른 참조를 가리 키기 시작하여 불변성이 보존됩니다.


0

답변에 늦었지만 Java에서 String 클래스 작성자의 간결한 메시지를 남기고 싶었습니다.

문자열은 일정합니다. 값을 만든 후에는 변경할 수 없습니다. 문자열 버퍼는 가변 문자열을 지원합니다. String 객체는 변경할 수 없으므로 공유 할 수 있습니다.

이 문서에서 문자열을 변경하고 다른 객체 (새롭거나 인턴되거나 오래된 것일 수 있음)를 반환하는 것이 무엇이든 파생 될 수 있습니다. 이에 대한 미묘한 힌트는 함수 서명에서 가져와야합니다. '왜 객체에서 함수가 상태 대신 객체를 반환하게 되었습니까?'라고 생각하십시오.

public String replace(char oldChar, char newChar) 

이 동작을 명시 적으로 만드는 또 하나의 소스 (바꾸기 기능 문서에서)

이 문자열에서 모든 oldChar 발생을 newChar로 바꾼 결과로 새 문자열을 리턴합니다.

출처 : https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)

  • 작가 Lee Boynton
  • 저자 아서 반 호프
  • 저자 마틴 부 홀츠
  • 작성자 Ulf Zibis

출처 : JavaDoc of String.


0

객체 문자열-메소드 자체는 "불변"으로 만들어집니다. 이 조치는 "letters.replace ("bbb ","aaa ");"를 변경하지 않습니다.

그러나 데이터를 할당하면 문자열 내용이 변경됩니다.

    letters = "aaa";
    letters=null;
    System.out.println(letters);
    System.out.println(oB.hashCode());
    System.out.println(letters);
    letters = "bbbaaa";
    System.out.println(oB.hashCode());
    System.out.println(letters);

// 문자열 Object의 해시 코드는 변경되지 않습니다.


0

경우 HELLO귀하의 문자열입니다 당신은 변경할 수 없습니다 HELLOHILLO. 이 속성을 불변 속성이라고합니다.

HELLO 문자열을 가리 키도록 여러 포인터 문자열 변수를 가질 수 있습니다.

그러나 HELLO가 char Array이면 HELLO를 HILLO로 변경할 수 있습니다. 예 :

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

프로그래밍 언어에는 변경할 수없는 데이터 변수가 있으므로 키, 값 쌍의 키로 사용할 수 있습니다.


0

간단한 예제로 설명하겠습니다


모든 문자 배열을 고려하십시오. 예 : char a [] = { 'h', 'e', ​​'l', 'l', 'o'}; 문자열 : String s = "hello";


문자 배열에서는 배열 반복을 사용하여 마지막 세 글자 만 인쇄하는 것과 같은 작업을 수행 할 수 있습니다. 그러나 문자열에서 우리는 새로운 문자열 객체를 만들고 필요한 부분 문자열을 복사해야하며 그 주소는 새로운 문자열 객체에 있습니다.

예 :

***String s="hello";
String s2=s.substrig(0,3);***

s2는 "hel"을 갖습니다;


-1

Immutable and Final의 Java 문자열은 변경하거나 수정할 수 없음을 의미합니다.

사례 1 :

class TestClass{  
 public static void main(String args[]){  
   String str = "ABC";  
   str.concat("DEF");  
   System.out.println(str);  
 }  
} 

출력 : ABC

이유 : 오브젝트 참조 str이 변경되지 않습니다. 사실 풀에 있고 전혀 참조되지 않은 새 오브젝트 "DEF"가 작성됩니다 (즉, 손실 됨).

사례 2 :

class TestClass{  
 public static void main(String args[]){  
   String str="ABC";  
   str=str.concat("DEF");  
   System.out.println(str);  
 }  
}  

출력 : ABCDEF

이유 :이 경우 str은 이제 새 오브젝트 "ABCDEF"를 참조하므로 ABCDEF를 인쇄합니다. 즉, 이전 str 오브젝트 "ABC"가 참조없이 풀에서 손실됩니다.


-1

String은 불변이기 때문에 반환 된 함수 값을 문자열에 할당하지 않으면 변경이 발생하지 않으므로 질문에서 스왑 함수 반환 값을 s에 할당하십시오.

s = swap (s, n1, n2); 문자열 s의 값이 변경됩니다.

나는 또한 어떤 순열 문자열을 얻기 위해 프로그램을 작성할 때 변경되지 않은 값을 얻었습니다 (모든 순열을 제공하지는 않지만 예를 들어 귀하의 질문에 대답합니다)

다음은 예입니다.

> import java.io.*;  public class MyString { public static void
> main(String []args)throws IOException {  BufferedReader br=new
> BufferedReader(new InputStreamReader(System.in));  String
> s=br.readLine().trim(); int n=0;int k=0;  while(n!=s.length()) {
> while(k<n){  swap(s,k,n); System.out.println(s); swap(s,k,n); k++; }
> n++; } }  public static void swap(String s,int n1,int n2) { char temp;
> temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s);
> sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString();
> } }

그러나 위의 코드에서 문자열의 순열 값을 얻지 못했습니다. 따라서 스왑 함수의 반환 값을 문자열에 할당하고 문자열 값을 변경했습니다. 반환 된 값을 할당 한 후 문자열의 순열 된 값을 얻었습니다.

/import java.util.*; import java.io.*; public class MyString { public static void main(String []args)throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
String s=br.readLine().trim(); int n=0;int k=0; 
while(n!=s.length()){ while(k<n){ s=swap(s,k,n); 
System.out.println(s); s=swap(s,k,n); k++; } n++; } } 
public static String swap(String s,int n1,int n2){
char temp; temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s); sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString(); return s; } }

-1
    public final class String_Test {

    String name;
    List<String> list=new ArrayList<String>();

    public static void main(String[] args) {

        String_Test obj=new String_Test();
        obj.list.add("item");//List will point to a memory unit- i.e will have one Hashcode value #1234

        List<String> list2=obj.list; //lis1 also will point to same #1234

        obj.list.add("new item");//Hashcode of list is not altered- List is mutable, so reference remains same, only value in that memory location changes

        String name2=obj.name="Myname"; // name2 and name will point to same instance of string -Hashcode #5678
        obj.name = "second name";// String is Immutable- New String HAI is created and name will point to this new instance- bcoz of this Hashcode changes here #0089

        System.out.println(obj.list.hashCode());
        System.out.println(list2.hashCode());
        System.out.println(list3.hashCode());

        System.out.println("===========");
        System.out.println(obj.name.hashCode());
        System.out.println(name2.hashCode());
    }
}

이런 식으로 넣어 생산합니다

1419358369 1419358369

103056 65078777

불변 개체의 목적은 일단 할당 된 후에는 그 값을 변경해서는 안된다는 것입니다. 구현에 따라 변경하려고 할 때마다 새 객체를 반환합니다. 참고 :이를 방지하기 위해 문자열 대신 문자열 버퍼를 사용할 수 있습니다.

마지막 질문에 :: u는 하나의 참조를 가지며 문자열 풀에는 2 개의 문자열이 있습니다. 참조를 제외하면 m! ss! ss! pp!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.