-
JAVA String 객체 와 String 리터럴(literal)Domain knowledge 2019. 10. 16. 23:23반응형
String strA = "Hello World"; String strB = new String("Hello World");
Java 에서 String 을 생성하는 방법은 위의 2가지가 있습니다.
기본적으로 print 문을 통해 출력시 같은 내용이 출력 됩니다.
출력 내용은 동일하나 내부 메모리상으로는 차이점을 보입니다.
String strA = "Hello World";
위와 같이 선언한 경우 상수풀에 저장된 메모리를 확인하여 동일한 데이터가 있다면 해당 데이터 주소를 참조합니다.
String strB = new String("Hello World");
위와 같이 선언한 경우 heap 메모리 상에 새로운 영역을 할당하여 해당내용을 저장후 메모리 주소를 참조합니다.
import org.junit.Test; import static org.junit.Assert.*; public class TestJava { String strA = "Hello World"; String strB = new String("Hello World"); String strC = "Hello World"; @Test public void strTest(){ assertSame(strA, strB); } @Test public void strTest2(){ assertSame(strA, strC); } @Test public void strTest3(){ assertEquals(true , strA.equals(strB)); } @Test public void strTest4(){ assertEquals(true , strA.equals(strC)); } }
위와 같이 테스트 코드를 작성하여 테스를 진행시 strTest 는 통과하지 못합니다.
assertSame의 경우 == 연산자로 비교를 하기 때문에 expected와 actual의 주소값을 비교하여 처리합니다.
그렇기 때문에 위의 설명한것처럼 다른 메모리 주소를 참조하고 있기 때문에 다른 Object로 판단하게 됩니다.
반면 str2의 경우는 동일한 리터럴이기 때문에 같은 메모리상에서 해당내용을 참조합니다.
그래서 동일한 메모리 주소를 공유하기 때문에 테스트를 통과하게 됩니다.
strA 와 strC가 같은 주소를 보기 때문에
만약 안에 있는 내용이 변경된다면 strA 와 strC의 내용이 같이 변경되게 됩니다.
그렇기 때문에 리터럴은 변경불가성(Immutable) 한 형태입니다.
equals의 경우는 맨 처음에는 주소값을 비교합니다.
주소가 다른경우에 그 뒤 넘겨받은 anObject가 String 일 경우 char[] 로 변환하여 각 char을 비교합니다.
이경우 주소와 관계없이 char의 문자를 각각 비교하기 때문에 문자만 동일하면 같은 것으로 판단하여 true을 리턴합니다.
[참고자료]
http://maedoop.dothome.co.kr/34/
https://madplay.github.io/post/java-string-literal-vs-string-object
https://vitalholic.tistory.com/15
반응형'Domain knowledge' 카테고리의 다른 글
이터레이션(Iteration)이란? (0) 2021.02.14 핸드셰이킹 (handshake) (0) 2020.11.10 FLOPS (Floating point operations per second) (0) 2020.10.05 클린 아키텍처(Clean Architecture) (0) 2020.01.18 러너블(Runnable)이란? (0) 2019.10.05 함수(Funtion)와 메소드(Method)의 차이 (0) 2019.09.21 BIG-O Notation (빅오표기법) (0) 2019.09.18 객체지향 디자인 5원칙 (SOLID) (0) 2019.09.18