알고리즘 문제를 풀다가 String으로 풀었을 때, char로 풀었을 때의 갭이 꽤 커서 머릿속에만 있는 개념을 정리하려고 한다.
(물론 형만 바꾼 것은 아니고 구현 방식도 조금 바뀌었기 때문에 완전히 형(format)차이라고만 말할 수는 없지만..
어떤 형을 선택해서 문제를 푸느냐에 따라 시간 차이가 꽤 커진다면.. 형 문제 때문이라고도 할 수 있지 않을까하는 구구절절한 마음..)
char은 문자다! 자바에서 선언하려면 이렇게 써야한다.
'a', 'B', 'c'
String은 문자열이다! 문자의 배열..! 문자열!
"a", "aB", "c"
컴공 수업을 처음 듣던 나는 문자 하나면 문자! 문자 여러개면 문자열! 이라고만 생각했다.
그렇지 않다는 것은 꽤 이후에 깨달았다..
Java에서는 크게 형을 두 가지로 생각할 수 있는데 기본형(primitive type)과 참조형이 있다.
기본형은 값을 저장한다고 생각하면 되는데, 우리가 흔히 생각하는 1, 1000, 1.0, false, true가 대표적인 예라고 생각하면 된다.
byte, short, char, int, float, double, boolean, long
기본형은 위의 8개만 있다.
true와 false를 저장하는 boolean
정수를 저장하는 byte, short, int, long
실수를 저장하는 float, double
문자를 저장하는 char
형의 크기에 따라 명시적 형변환, 묵시적 형변환이 나뉘는데
byte < short, char < int < long < float < double
위와 같다.
그래서 흔히들 int형은 간단하게 long형으로 쓸 수 있지만, long형은 쉽사리 int형으로 쓸 수 없다.
훨씬 크기 때문이다.
예를 들면, int형의 크기를 훨씬 넘어서는 값으로 인해 오버플로우가 나서 -123879 이런 식으로 값이 나오는 경우가 있는데
이럴 때 int형이 아닌 long 자료형에 넣어주면 값이 제대로 출력되는 경우가 있다.
실수형은 무조건 정수형보다 크다. float은 long보다 크기는 작지만 소수점 영역을 표시하기 때문에 더 크다.
(요 부분은 더 공부해보면 좋을 것 같다)
형변환 이야기로 갑자기 빠졌는데, 아무튼 char는 기본형이다!
그리고 기본형의 저장공간은 스택이다!
String은 참조형이다!
참조형의 저장공간은 힙이다!
String은 좀 재밌는데,
String을 선언할 때 아래와 같이 두 가지 방법으로 선언할 수 있다!
String a = "hello~";
String a = new String("hello~");
음.. 다른가...?
싶을 수도 있는데
String a = "hello~";
String b = "hello~";
String c = new String("hello~");
// a와 b 비교
System.out.println(a == b); // true
// a와 c 비교
System.out.println(a == c); // false
// b와 c 비교
System.out.println(b == c); // false
자바 내에서 굉장히 다르게 평가한다는 것을 알 수 있다.
String을 만드는 방법은 두 가지이기 때문이다.
1. new로 객체를 생성하는 방법
2. 문자열 리터럴로 생성하는 방법
new로 객체를 생성하게 되면 힙 영역에 객체를 생성하는 것과 동일하다.
문자열 리터럴로 생성하는 방법은 조금 다른데, String constant pool에 할당된다.
자바 8부터는 String constant pool이 힙 영역에 해당되어서
생성 방법은 달라도 생성 영역은 동일하다.
"hello" 라는 문자열 리터럴을 String constant pool에 할당하면
다음에 문자열 리터럴로 "hello"를 생성하면 이전에 생성했던 "hello" 문자열 리터럴을 재사용하게 된다.
재사용이 가능하게 하는 건 String의 메소드 중 하나인 intern() 때문인데,
설명을 참고하면 pool에 이미 존재하는 String과 일치하는 String을 만들려고 하면
pool에 존재하는 String을 리턴한다고 한다.
new로 String 객체를 생성할 경우 같은 문자열을 가진 String 객체가 이미 존재한다고 하더라도 재사용하지 않는다.
자바 소스 파일(.java)이 클래스 파일(.class)로 컴파일되고 JVM이 올라갈 때,
JVM은 String Constant Pool에 동일한 문자열이 있는지 확인하고 이미 존재한다면 재사용을 하고 없는 경우 새로운 문자열을 만든다.
참고 자료
https://tecoble.techcourse.co.kr/post/2020-09-07-dive-into-java-string/