[Java] 6.String
자바의 String에 대한 설명
String
원문 참고 :https://www3.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html
자바에서 String은 참조형 자료형으로서 특별한 대우를 받는다. 왜냐하면 , String(문자열)은 프로그램에서 아주 빈번하게 사용되기 때문이다.
자바를 만든 디자이너는 객체지향 언어에서 기본형(primitive)자료형을 유지하기를 원했는데 , 이 말을 다시 하자면 정해진 자료 예를들면 숫자나, 문자 이런것들을 미리 저장해서 꺼내쓰는 방법으로 효율성을 높이려 했다는 것이다.
이러한 기본형 자료형은 Stack 이라는 메모리 공간에 저장되는데, 적은 저장 공간이 요구되고 조작하기가 쉽다.
반면 참조형 (Object) 들은 heap이라는 메모리 공간에 저장된다. 이것은 복잡한 메모리관리와 더 많은 저장공간을 필요로 한다.
따라서, 효율성을 위해 자바의 스트링은 이러한 기본형 자료와 참조형 자료의 사이에서 디자인되었다.
결과적으로는 기본형이 가지는 특징과 참조형이 가지는 특징들을 같이 가지고 있게 되는 것이다.
그 중 하나는 “ + “ 연산자를 사용하는것이 가능 하다는 것이다. String은 원래 기본형만이 사용 가능한 + 연산자를 통해서 String + String 연산을 할 수 있다.
예를 들면,
String a="나";
String b="는"
system.out.println(a+b)// 결과 ==> 나는
이런식으로 두 문자열을 붙이는것이 가능하다는것이다.
또한 2가지의 방법으로 선언과 초기화가 가능하다.
String a="이렇게";
String b= new String("둘다 가능해요")
위의 예처럼 기본형 변수를 선언하는것처럼 선언하는것도 가능하고, 참조형 변수를 선언하는것 처럼 new 를 이용해서 변수를 선언하고 초기화 하는것도 가능하다.
그렇다면, 문자열의 비교도 기본형처럼 할 수 있을까? 결론적으론 가능하지만, 특정 상황에서만 가능하다.
원문 참고라고 올려놓은 페이지의 예시를 쓰자면,
String s1 = "Hello"; // String literal
String s2 = "Hello"; // String literal
String s3 = s1; // same reference
String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
이게 뭔소린가 싶겠지만, 한 번 설명해 보겠다.
s1 ~ s3 까지는 기본형 변수를 사용하는것처럼 선언했고 s4~s5 는 참조형 객체를 사용하는 방식으로 선언했다. 기본형 방식으로 사용한것은 위의 그림처럼 변수들이 하나의 Hello를 가리키고 있는 반면에, 참조형으로 선언한 String의 경우에는 같은 Hello라도 따로 저장된 Hello를 가리킨다. 그래서 이게 무슨차인데? 아래를 보자
system.out.println(s1==s2); //true 기본형으로사용
system.out.println(s4==s5);//false 참조형으로사용
이런 결과가 나온다 다 같은 Hello지만 , 변수가 어떤 값의 주소를 가리키냐에 따라서 결과가 달라지는 것이다.
또한, String을 기본형으로 사용할 때, 불변(immutable)이라는 특징을 가지고 있다. String이 한 번 선언되면, 그 할당된 주소의 값은 바뀌지 않는다. 참조형일때는 값의 변경에 대해 영향을 받는다.
이말을 다시하면, 위의 그림에서 Common Pool의 Hello라고 써있는 공간의 값을 변경시킬 수 없다는 것이다. 그래서 기본형으로 String 을 사용할 때 , 값을 바꾼다는것은 새로운 메모리를 할당하게 되는것이고, 값이 빈번하게 바뀐다면 ? 메모리의 낭비로 이어질 것이다.
따라서 String의 값이 자주 바뀔때, 우리는 참조형으로 사용하거나, StringBuffer 또는 StringBuilder를 사용하여 값을 선언하고 변경해야 메모리의 낭비를 줄일 수 있다. 위의 두 클래스는 String의 값이 변경 될 때 새로 메모리를확보하여 저장하는것이 아니라 기존의 메모리값을 변경하는 방식으로 처리되기 때문에 변경되는 String값의 메모리 사용 측면에서 훨씬 효율적이라고 할 수 있겠다.
buffer와 builder또한 차이가 있는데 , 이는 다음에 시간이 나면 다뤄 보도록 하겠다.
오늘 String은 여기까지 그럼 안녕! 요호홍