다음 예를 고려하십시오.
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
객체가 아니라 객체에 대한 참조입니다. "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 실제로 문자열 (및 기타 불변 객체)을 변경 하는 것이 가능합니다. 리플렉션이 필요하고 매우 위험하며 프로그램을 실제로 파기하지 않는 한 절대 사용해서는 안됩니다.
답변
str
참조 하는 객체 는 변경 될 수 있지만 실제 String
객체 자체는 변경할 수 없습니다.
는 String
문자열을 포함하는 객체 "Hello"
및 "Help!"
따라서 그들은 불변하기 때문에, 그 값을 변경할 수 없다.
String
객체 의 불변성이 객체를 가리키는 참조가 변경 될 수 없음을 의미하지는 않습니다.
str
참조가 변경되는 것을 막을 수있는 한 가지 방법은 다음과 같이 선언하는 것입니다 final
.
final String STR = "Hello";
이제 또 다른를 할당하려고 String
하는 STR
컴파일 오류가 발생합니다.
답변
Light_handle 변수 와 Pass-by-Value Please (컵 크기 계속)에 대한 이야기 인 컵 크기를 읽는 것이 좋습니다 . 위의 게시물을 읽을 때 많은 도움이 될 것입니다.
읽어 보셨습니까? 예. 좋은.
String str = new String();
“”라는 새로운 “원격 제어”를 작성하고이를 str
값 new String()
(또는 ""
)으로 설정합니다.
예를 들어 메모리에서 다음을 생성합니다.
str --- > ""
str = "Hello";
그러면 리모콘 ” str
” 이 변경 되지만 원래 문자열은 수정되지 않습니다 ""
.
예를 들어 메모리에서 다음을 생성합니다.
str -+ ""
+-> "Hello"
str = "Help!";
그러면 리모컨 ” str
“이 (가) 변경되지만 원래 문자열 ""
이나 리모컨이 현재 가리키는 객체는 수정되지 않습니다 .
예를 들어 메모리에서 다음을 생성합니다.
str -+ ""
| "Hello"
+-> "Help!"
답변
몇 부분으로 나눕니다
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을 최종 클래스 로 결정했습니다. 그렇지 않으면 누구나 문자열 값을 수정하고 변경할 수 있습니다. 이것이 조금 도움이되기를 바랍니다.
답변
처음 참조한 문자열 객체는 str
변경되지 않았으므로 str
새 문자열 객체를 참조하기 만하면됩니다.
답변
문자열은 변경되지 않으며 참조는 변경됩니다. 불변성과 final
필드 개념을 혼동하고 있습니다. 필드가로 선언되면 final
, 일단 할당 된 필드는 재 할당 할 수 없습니다.
답변
질문의 교체 부분과 관련하여 다음을 시도하십시오.
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!