2024-05-17 작성

Integer.valueof() vs Integer.parseint() 차이 및 소스분석


자바에서 문자열을 int형 타입으로 형변환할 때, 흔히 Integer.parseInt() 또는 Interger.valueOf() 메서드를 사용한다. 이 둘의 차이점과 실제 Java API 소스를 가볍게 살펴보려고 한다.

Integer.valueof() vs Integer.parseint() 차이

  • parseInt() : int 타입을 반환
  • valueOf() : Integer 래퍼(wrapper) 객체를 반환

Java 내부 API 까보기

Integer.parseInt 메서드는 기본데이터 타입인 int 으로 반환한다.

public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s, 10);
}

Integer.valueOf 메서드는 Integer 타입으로 반환한다.

public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

위 메서드 둘 다 결국엔 아래의 parseInt를 호출한다. 매개변수 s는 대상 문자열이고  radix는 10진수이다. 순서대로 문자열 null 체크, 진수 체크를 하고 나서 +/- 부호 체크 등을 검증하고 나서 최종적으로 return 값에 결괏값이 담긴다.

public static final int MIN_RADIX = 2;
public static final int MAX_RADIX = 36;
@Native public static final int MIN_VALUE = 0x80000000;
@Native public static final int MAX_VALUE = 0x7fffffff;

// 생략...

public static int parseInt(String s, int radix) throws NumberFormatException {

    if (s == null) {
        throw new NumberFormatException("Cannot parse null string");
    }

    if (radix < Character.MIN_RADIX) {
        throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
    }

    if (radix > Character.MAX_RADIX) {
        throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
    }

    boolean negative = false;
    int i = 0, len = s.length();
    int limit = -Integer.MAX_VALUE;

    if (len > 0) {
        char firstChar = s.charAt(0);
        if (firstChar < '0') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+') {
                throw NumberFormatException.forInputString(s, radix);
            }

            if (len == 1) { // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s, radix);
            }
            i++;
        }
        int multmin = limit / radix;
        int result = 0;
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            int digit = Character.digit(s.charAt(i++), radix);
            if (digit < 0 || result < multmin) {
                throw NumberFormatException.forInputString(s, radix);
            }
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s, radix);
            }
            result -= digit;
        }
        return negative ? result : -result;
    } else {
        throw NumberFormatException.forInputString(s, radix);
    }
}

비슷한 알고리즘 문제 풀이를 하다가 느낀 거지만, 잘 만들어진 API를 잘 가져다 쓰는 것도 중요하지만 내부 로직이 어떻게 짜여 있는지 의식적으로 살펴보는 것도 중요하다고 생각한다.