Java에서 문자열을 어떻게 복사해야합니까?


199
    String s = "hello";
    String backup_of_s = s;
    s = "bye";

이 시점에서 백업 변수는 여전히 원래 값 "hello"를 포함합니다 (이것은 String의 불변성 때문입니까?).

그러나이 방법으로 문자열을 복사 하는 것이 실제로 안전 합니까 (물론 일반 가변 객체를 복사하는 것이 안전하지 않습니까?) :

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

다시 말해,이 두 코드 조각의 차이점은 무엇입니까?


편집-첫 번째 스 니펫이 안전한 이유 :

이미 제공된 좋은 답변 (기본적으로 2 개의 스 니펫 간의 성능 차이 문제에 중점을 두었습니다)을 기반으로 좀 더 자세히 설명하겠습니다.

Java에서는 문자열을 변경할 수 없습니다. 즉, 문자열 객체는 생성 후에 수정할 수 없습니다. 그 후,

String s = "hello";새로운 String 인스턴스를 생성하고 주소를 s( s인스턴스 / 객체에 대한 참조) 할당

String backup_of_s = s;새 변수를 backup_of_s만들고 초기화하여 현재 참조하는 객체를 참조합니다 s.

참고 : 문자열 불변성은이 객체가 수정되지 않도록 보장합니다. 백업은 안전합니다

참고 2 : Java 가비지 수집 메커니즘은이 객체가 하나 이상의 변수 ( backup_of_s이 경우)에 의해 참조되는 한 파괴되지 않도록합니다.

마지막으로, s = "bye";불변성 때문에 유일한 String 인스턴스 인 다른 String 인스턴스를 만들고 s변수를 수정 하여 새 객체를 참조하도록합니다.

답변:


141

문자열은 변경할 수 없으므로 두 버전 모두 안전합니다. 그러나 후자는 효율성이 떨어집니다 (추가 개체를 생성하고 경우에 따라 문자 데이터를 복사 함).

이를 염두에두고 첫 번째 버전이 선호됩니다.


15
불변성은 그것과 아무 관련이 없습니다. 단순히 객체 참조가 작동하는 방식입니다. 동등한 StringBuilder 예제를 제공 할 수 있습니다.
GriffeyDog

1
@BalusC, 새로운 String ()이 JVM의 문자열 풀에서 어떻게 무언가를 만들 수 있는지 알 수 없습니다. 문자열 리터럴과 intern ()을 통해 풀에 커밋 된 문자열 만 풀에 있습니다.
Snicolas

3
@GriffeyDog : 나는 문자 그대로 질문을 읽고 있습니다. 내가 말하는 것은 누군가가 문자열을 수정할지도 모른다는 두려움없이 문자열 객체에 대한 참조를 제공하는 것이 안전하다는 것입니다.
NPE

2
@GriffeyDog 귀하의 의견이 매우 오해의 소지가 있습니다. 불변성은 첫 번째 스 니펫을 안전하게 만드는 이유입니다. 왜 "it"과 관련이 없다고 말할까요?
Sébastien

5
@Sebastien 모든 것은 s다른 객체 ( String"bye") 를 참조하기 위해 참조 변수 를 재 할당하는 것 입니다. 참조 변수 backup_of_s가 참조하는 것 ( String"hello") 에는 영향을 미치지 않습니다 . 내가 말했듯이, 나는 불변 이 아닌StringBuilder s 와 동등한 예제를 제공 할 수 있습니다 . 내 의견은 주로 OPs 문에 관한 것입니다 .이 시점에서 백업 변수에는 여전히 원래 값 "hello"가 포함됩니다 (이것은 String의 불변성 때문입니까?).
GriffeyDog 2015 년

22

문자열은 불변의 객체 이므로 참조 된 객체를 변경할 수 없으므로 참조를 복사하여 복사 할 수 있습니다 ...

따라서 문제없이 첫 번째 예제에서와 같이 복사 할 수 있습니다.

String s = "hello";
String backup_of_s = s;
s = "bye";

10

두 번째 버전은 단순히 그렇게 할 필요가 없을 때 추가 문자열 객체를 생성하기 때문에 효율성이 떨어집니다.

불변성은 첫 번째 버전이 예상 한대로 동작하므로 선호되는 방식입니다.


0

두 번째 경우는 문자열 풀 측면에서 비효율적이므로 반환 참조에서 intern ()을 명시 적으로 호출하여 인턴으로 만들어야합니다.


-16
String str1="this is a string";
String str2=str1.clone();

이런 복사는 어떻습니까? 새로운 사본을 얻는 것이 더 좋습니다. 따라서 추가 데이터에서 참조되고 수정 str1될 때 데이터에 영향을 미치지 않습니다 str2.


3
String불변입니다. 문자열 복제는 의미가 없습니다.
Vladimir
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.