Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9 JShell에서 문자열(String)을 구현하고 활용하는 방법

JShell은 Java 9에서 처음 공식적으로 도입된 REPL(Read-Eval-Print Loop) 애플리케이션입니다. 명령줄(command-line) 프롬프트 환경에서 간단한 Java 프로그램과 작은 로직들을 즉시 실행하고 평가할 수 있는 도구로, 문장(statement), 간단한 프로그램, 루프(loop), 표현식(expression) 등을 손쉽게 테스트할 수 있습니다. 입력을 읽고 평가한 후 결과를 출력하는 방식으로 동작하기 때문에 학습이나 빠른 프로토타이핑에 매우 유용합니다.

아래 예제를 통해 JShell에서 String 클래스의 다양한 사전 정의된(pre-defined) 메서드를 활용해 문자열을 구현하는 방법을 단계별로 살펴보겠습니다.

문자열 생성과 substring() 메서드

jshell> String str = "{abcd}";
str ==> "{abcd}"

jshell> str.substring(2, str.length() - 1)
$7 ==> "bcd"

먼저 문자열 변수 str을 선언한 뒤, substring() 메서드로 중괄호를 제외한 내부 문자열만 추출했습니다. substring(2, length-1)은 인덱스 2부터 마지막 문자 앞까지의 부분 문자열인 "bcd"를 반환합니다.

== 연산자와 equals() 메서드의 차이 이해하기

jshell> String s1 = new String("abcd");
s1 ==> "abcd"

jshell> String s2 = new String("abcd");
s2 ==> "abcd"

jshell> s1 == s2
$10 ==> false

jshell> s1.equals(s2)
$11 ==> true

new 키워드로 생성한 문자열은 힙(heap) 영역에 서로 다른 객체로 만들어집니다. 따라서 참조(주소)를 비교하는 == 연산자의 결과는 false가 되고, 실제 내용을 비교하는 equals() 메서드의 결과는 true가 됩니다.

jshell> String s3 = "abcd";
s3 ==> "abcd"

jshell> String s4 = "abcd";
s4 ==> "abcd"

jshell> s3 == s4
$14 ==> true

jshell> s3.equals(s4)
$15 ==> true

jshell> s1 == s3
$16 ==> false

jshell> s1.equals(s3)
$17 ==> true

반면 문자열 리터럴 방식으로 생성하면 JVM의 문자열 상수 풀(String Constant Pool)에 저장되어, 동일한 내용의 리터럴은 하나의 객체를 공유하게 됩니다. 그래서 s3와 s4를 ==로 비교하면 true가 반환되지만, new로 만든 s1과는 주소가 다르므로 false가 나옵니다.

컴파일 시점에 결합된 문자열 리터럴

jshell> String s5 = "a" + "bcd";
s5 ==> "abcd"

jshell> s3 == s5
$19 ==> true

"a" + "bcd"처럼 상수끼리의 문자열 결합은 컴파일 시점에 "abcd"로 최적화됩니다. 따라서 s5 역시 문자열 풀에 있는 동일한 객체를 가리키므로 s3 == s5의 결과는 true입니다.

getBytes()로 바이트 배열 변환하기

jshell> "abcd".getBytes()
$20 ==> byte[4] { 97, 98, 99, 100 }

jshell> "abcd".getBytes("UTF-16")
$22 ==> byte[10] { -2, -1, 0, 97, 0, 98, 0, 99, 0, 100 }

getBytes() 메서드는 문자열을 플랫폼 기본 문자셋의 바이트 배열로 변환하며, 인코딩 이름을 인자로 전달하면 해당 문자셋(예: UTF-16) 기준으로 변환합니다. UTF-16 결과의 첫 두 바이트(-2, -1)는 BOM(Byte Order Mark)에 해당합니다.

split()으로 문자열 분리하기

jshell> String raw = "1|2|3|4";
raw ==> "1|2|3|4"

jshell> raw.split("\\|")
$24 ==> String[4] { "1", "2", "3", "4" }

split() 메서드는 정규표현식을 기준으로 문자열을 나눕니다. 파이프(|)는 정규표현식에서 OR 연산을 의미하는 특수 문자이므로, 백슬래시로 이스케이프하여 구분자로 사용해야 합니다.

정리

JShell을 활용하면 별도의 클래스 파일 작성이나 컴파일 과정 없이 문자열 관련 메서드들을 대화형으로 실험할 수 있습니다. 특히 ==equals()의 차이, 문자열 상수 풀의 동작 원리 같은 개념을 코드 한 줄씩 즉시 확인할 수 있어 Java 학습과 디버깅에 큰 도움이 됩니다.