[Java] String.valueOf와 + ""의 차이

Bam·2025년 6월 5일
0

Java

목록 보기
99/100
post-thumbnail

문자열로 변환하기

Java에서 일반 타입들을 문자열로 변환하기 위해 String.valueOf() 또는 +""를 사용합니다.

객체를 문자열로 변환하는 경우에는 toString()을 사용합니다.

여기서 한 가지 궁금한 점이 생겼습니다. 두 방식 중 어떤 방식을 사용하는게 더 좋을까요?

결론부터 이야기하자면,
+""가 근소하게 빠르지만 String.valueOf()의 사용을 권장드립니다.

String.valueOf() VS +""

일단 동작 자체는 문자열이 아닌 타입의 값을 문자열로 변환해준다는 것으로 동일한 동작을 보여줍니다. 그러나 두 방식은 내부 동작 방식이 완전히 다른 방식을 가지고 있습니다.

그래서 다음과 같은 코드를 실행해보면 수행 속도가 +""쪽이 더 빠르다는 것을 볼 수 있습니다.

public class Main {

    public static void main(String[] args) {
    
        int n = 1_000_000;
        int loop = 1_000_000;

		//String.valueOf() 수행시간 측정
        Long start = System.nanoTime();
        for (int i = 0; i < loop; i++) {
            String numToStr = String.valueOf(n);
        }
        Long end = System.nanoTime();
        System.out.println("String.valueOf 평균 속도: " + ((end - start) / loop) + "ns");

		//+"" 수행시간 측정
        start = System.nanoTime();
        for (int i = 0; i < loop; i++) {
            String numToStr = n + "";
        }
        end = System.nanoTime();
        System.out.println("+'' 평균 속도: " + ((end - start) / loop) + "ns");
    }
}

nanosecond 단위라서 그다지 큰 차이로 느껴지지는 않을 수 있지만 명백하게 속도차이가 존재하죠?

두 방식의 내부 동작을 살펴보고 왜 이런 차이가 발생하는지 알아보도록 하겠습니다.

String.valueOf()의 동작 방식

OpenJDK 구현 기준으로 String.valueOf()는 다음과 같이 동작합니다. (int형에 대해서만 이야기합니다)

다른 타입 변환도 궁금하시다면 OpenJDK GitHub를 참조해주세요.

int형 값이 들어오면 Integer Wrapper 클래스를 이용하여 toString()을 호출하여 문자열로 변환을 시도하게 됩니다.

+ ""의 동작 방식

+ ""+ 연산자의 문자열 연산을 수행합니다. 왜냐하면 앞에 어떤 타입이 오던간에 나머지 피연산자가 문자열 ""이기 때문입니다.

Java Language Specification 문서를 보시면 다음과 같이 + 연산자의 문자열 연산은 높은 성능 연산을 위해 StringBuffer와 같은 클래스 또는 비슷한 클래스를 이용해서 변환한다고 명시되어 있습니다.

해당 부분 원문
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.

공식문서 전문은 여기서 참조하실 수 있습니다.

참고로 공식문서에 적힌 클래스는 StringBuffer지만 최근 JVM은 StringBuilder라는 더 빠른 속도의 클래스가 존재하기 때문에 StringBuilder를 사용하고 있다고 합니다.

그래서 +""가 빠르긴하지만...

String.valueOf()는 내부적으로 래퍼 클래스의 toString()을 호출하는 과정을 거치고 +""는 빠른 성능을 위한 StringBuilder 클래스를 사용하기 때문에 결과적으로 +""의 수행 속도가 더 빨랐다는 것을 확인할 수 있었습니다.

결론은 String.valueOf()가 권장된다!

더 빠르긴하지만 빠르긴하지만 나노초라는 아주 작은 시간 단위이기 때문에 거의 모든 상황에서는 무시할 수 있는 시간적 차이라고 합니다.

그래서 결국엔 시간적 우세가 있지만 자바 표준 문법이고 더 좋은 가독성, NULL 안정성을 가진 String.valueOf()를 사용하는 것이 권장된다라고 말씀드릴 수 있습니다.

String.valueOf()는 NULL이 발생해도 문자열로 변환하여 "Null"이라는 문자열을 반환합니다.
반면, + ""는 NULL이 발생하면 NullPointerException을 반환하기 때문에 String.valueOf()가 NULL에 대해 더 높은 안정성을 보장한다고 할 수 있습니다.


번외. String.valueOf()와 toString()

String.valueOf()와 toString()은 객체를 문자열로 변환할 때 사용합니다.

이 두 메소드의 차이도 방금 설명한 NULL 안정성에 따라 동작차이를 보여줍니다.

String.valueOf()는 상기했듯 NULL값이 들어와도 "NULL"이라는 문자열 결과를 반환합니다. 반면 toString()은 NULL값이 들어오면 NullPointerException을 반환하게 됩니다.

따라서 이 경우에도 NULL 안정성을 위해 String.valueOf()를 사용하는 것이 권장됩니다.

1개의 댓글

comment-user-thumbnail
2025년 6월 26일

덕분에 알아갑니다 감사합니다.

답글 달기