String Concatenation Operator

Dongwoo Joo·2024년 12월 10일

java

목록 보기
5/8

문자열 연결 연산자

Java 언어는 문자열 연결 연산자( + )와 다른 객체를 문자열로 변환하는 데 대한 특별한 지원을 제공합니다. 문자열 연결 및 변환에 대한 추가 정보는 Java™ 언어 사양을 참조하세요.

구현 참고:
문자열 연결 연산자의 구현은 컴파일러가 궁극적으로 Java™ 언어 사양을 준수하는 한 Java 컴파일러의 재량에 달려 있습니다. 예를 들어, javac 컴파일러는 JDK 버전에 따라 StringBuffer, StringBuilder 또는 java.lang.invoke.StringConcatFactory로 연산자를 구현할 수 있습니다. 문자열 변환의 구현은 일반적으로 Object에서 정의하고 Java의 모든 클래스에서 상속하는 toString 메서드를 통해 이루어집니다.

여기까지 읽어보면 Object.toString()을 사용한다고 나와있다.

docs의 설명

자바 23버전을 참조해보자.
15.18.1. String Concatenation Operator

If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.
-> 피연산자 표현식이 문자열인 경우, 다른 피연산자에 문자열 변환을 수행하여 런타임에 문자열을 생성한다.

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
-> 문자열 연결의 결과는 두 피연산자 문자열을 연결한 문자열 객체에 대한 참조입니다. 새로 생성된 문자열에서 왼쪽 피연산자의 문자는 오른쪽 피연산자의 문자보다 앞에 옵니다.

The String object is newly created (§12.5) unless the expression is a constant expression (§15.29).
-> 표현식이 상수 표현식(§15.29)이 아니면 문자열 객체는 새로 생성됩니다(§12.5).

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
-> 구현은 중간 문자열 객체를 생성한 다음 삭제하는 것을 피하기 위해 한 단계에서 변환과 연결을 수행하기로 선택할 수 있습니다. 반복되는 문자열 연결의 성능을 높이기 위해 Java 컴파일러는 StringBuffer 클래스 또는 유사한 기술을 사용하여 표현식 평가로 생성되는 중간 문자열 객체의 수를 줄일 수 있습니다.

For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
-> 기본 유형의 경우 구현은 기본 유형에서 문자열로 직접 변환하여 래퍼 객체 생성을 최적화할 수도 있습니다.

§5.1.11을 살펴보자.

피연산자를 문자열로 변환하는 것은 new 생성자 함수를 통해 premitive type의 reference value를 생성한 뒤, 각 reference type 클래스의 toString() 메서드(Object 클래스의 toString을 오버라이딩)를 사용하여 변환한다.

왜 GPT는 String.valueOf() 를 사용한다고 하는 것일까?

효율성

String.valueOf()는 premitive type의 값을 문자열로 변환하는 표준 메서드이다. 내부적으로 캐싱된 문자열 객체를 재사용하거나, 필요한 경우 문자열을 생성한다.
(참고: cache pool)

이 때, new Integer()은 사용되지 않는다.
계속 객체를 생성하는 것은 비효율적이고 메모리 낭비가 크기 때문에 컴파일러에서 배제된다.

컴파일러는 항상 StringBuilder와 String.valueOf()를 결합해 문자열 + 숫자 연산을 처리하며, new Integer()는 절대 사용되지 않는다.

int a = 1;
String result = "a" + a;
위 코드는 다음과 같이 변환된다.
String result = new StringBuilder().append("a").append(String.valueOf(a)).toString();

분석결과

Java의 String concatenation Operator는 피연산자의 문자열이 있을 때, 다른 피연산자를 문자열로 변환한다.
이 때, 컴파일러의 결정에 따라 문자열 변환 방식이 바뀐다.

  • 공식문서: premitive type의 reference value를 생성하고 toString() 메서드를 사용해서 변환한다.
    Integer a = new Integer(1); a.toString();
    반복되는 문자열의 성능을 높이기 위해 StringBuffer, StringBuilder 등 유사한 기술을 사용하여 문자열 객체 수를 줄인다.

  • GPT: String.valueOf 메서드를 사용해서 문자열을 변환한다.
    -128 127까지의 숫자는 캐싱된 문자열을 사용하고, 128 부터는 새로운 문자열을 생성하여 효율적인 메모리 관리를 한다.

결론

정확한 내용을 알려면, 컴파일된 소스코드를 확인해야 한다.
다만, 위의 내용으로 미루어 보았을 때,
문자열 연결 연산자를 사용하여 문자열을 연결할 때는 성능을 높이기 위해 StringBuilder, StringBuffer를 사용하며, 숫자는 String.valueOf() 메서드를 통해 문자열로 변환된다.

profile
pursue nature

0개의 댓글