시작하며.
자바 기본 클래스 중에서도 자주 사용하는 String 클래스에 대한 이해를 높여보자.
String을 선언하는 두가지 방법.
String은 자바에서 문자열을 사용하기 위한 클래스이다.
아주 많이 활용하기때문에 생성 할때도 어떤 차이가 있는지 알아보자.
String loopy = new String("loopyString"); // String 클래스의 생성자 매개변수로 생성
String loopy1 = "loopy"; // 문자열 상수를 가리키는 방식으로 생성
String loopy2 = "loopy"; // 문자열 상수를 가리키는 방식으로 생성
new 예약어로 사용해 객체를 생성하는 경우 "loopyString" 문자열을 위한 메모리가 할당 되고 새로운 객체가 생성
두번째, 세번째 줄 처럼 생성자를 이용하지 않고 값을 할당해주면 상수 풀(constant pool)라는 상수 값을 저장하는 공간에서
문자열 상수 "loopy"의 메모리 주소를 가리키게 된다.
따라서 loopy1과 loop2의 주소 값이 같게 됨.
public class StringClassTest {
public static void main(String[] args) {
String loopy1 = new String("loopyString"); // String 클래스의 생성자 매개변수로 생성
String loopy2 = new String("loopyString"); // String 클래스의 생성자 매개변수로 생성
String loopy3 = "loopy"; // 문자열 상수를 가리키는 방식으로 생성
String loopy4 = "loopy"; // 문자열 상수를 가리키는 방식으로 생성
System.out.println(loopy1 == loopy2); // false - 인스턴스가 매번 새로 생성되어 주소 값이 다름
System.out.println(loopy1.equals(loopy2)); // true - 문자열 값은 같으니 true
System.out.println(loopy3 == loopy4); // true - 상수 풀의 문자열 "loopy"를 같은 주소 가르킴
System.out.println(loopy3.equals(loopy4)); // ture // 문자열도 동일하니 true
}
}
String 클래스의 final byte[] 변수 ( java 8까지는 char[] 변수).
// 참고.
String 클래스에서 char 배열 대신 byte 배열을 사용하여 문자열 데이터를 저장하는 것은 Java의 내부적인 구현 방식입니다. Java의 String 클래스는 원래부터 char 배열을 사용하여 문자열 데이터를 저장하였으며, 이는 문자열의 유니코드 문자를 표현하기 위한 자바의 기본 타입인 char를 활용한 것입니다.
그러나 Java 9 이후부터 String 클래스의 내부 구현이 변경되어 char 배열 대신 byte 배열을 사용하게 되었습니다. 이 변경은 문자열의 인코딩과 관련이 있습니다. 이전에는 String 클래스는 항상 UTF-16 인코딩을 사용하여 문자열 데이터를 저장했지만, Java 9부터는 인코딩 방식을 바이트 배열로 변경하여 효율성을 개선하고 메모리 사용량을 줄이는 목적으로 이루어졌습니다.
따라서 Java 9 이전의 버전에서는 String 클래스의 내부 구현은 char 배열을 사용하며, Java 9 이후의 버전에서는 byte 배열을 사용합니다. 개발자 관점에서는 문자열을 다루는 방식에는 큰 차이가 없으며, 여전히 String 클래스를 사용하여 문자열을 다룰 수 있습니다.
String 클래스는 자바 9 이상부터 char[] value에서 byte[] value로 변경되어 사용된다. 자세한 내용은 위를 참고 바란다.
vaule는 private final 로 선언되어 문자열을 변경할 수 없다.따라서 한번 생성된 문자열은 변경되지 않는다. 즉 immutable 이다.
만약 문자열 a 와 b를 연결해 새로운 문자열을 만든다면 이는 a, b 가 변하는 것이 아닌 새로운 문자열이 생성 된다.
String java = new String("java");
String programming = new String("Programming");
System.out.println(java); // java
System.out.println("처음 문자열 주소 값 : " + System.identityHashCode(java));
// 처음 문자열 주소 값 : 798154996
java = java.concat(programming);
System.out.println(java); // javaProgramming
System.out.println("연결 후 주소 값 : " + System.identityHashCode(java));
// 연결 후 주소 값 : 1555009629
두번째 java 변수 출력 부분을 보면 "javaProgramming"이 출력되는걸 확인할 수 있는데
이는 원래 java 변수의 값인 "java" 가 값 자체가 변한게 아니고
합쳐진 "javaProgramming"이라는 새로운 문자열이 생성되어 이를 가리키는 것
그렇기 떄문에 문자열의 변동이 많은 경우에는 StringBuilder 또는 StringBuffer를 사용하면
메모리 사용량을 줄일 수 있다.
'BACKEND > JAVA' 카테고리의 다른 글
자바 - 스트림(Stream) (0) | 2023.06.04 |
---|---|
자바 클래스 - Wrapper 클래스 (0) | 2023.06.03 |
자바 클래스 - Object 클래스 (0) | 2023.05.27 |
자바 오름차순/내림차순 정렬하기 - Arrays.sort() 함수 (0) | 2023.05.26 |
함수형 프로그래밍과 람다식(Lambda expression) (1) | 2023.05.21 |