parseInt 与 valueOf 区别

5/7/2022 Java

心灵鸡汤

每天给自己一个希望,试着不为明天而烦恼,不为昨天而叹息,只为今天更美好

# 一:parseInt

# 1.1 源码

package java.lang;

public final class Integer extends Number implements Comparable<Integer> {

	/**
	 * 将字符串参数解析为第二个参数指定的进制中的有符号整数。
	 * 字符串中的字符必须都是指定进制的数字,
	 * (由 Character.digit(char, int) 是否返回非负值决定),
	 * 除了第一个字符可能是 ASCII 减号 '-' ('\u002D') 表示负值,或 ASCII 加号 '+' ('\u002B') 表示正值。
	 * 返回结果整数值。
	 * 
     * 如果发生以下任何一种情况,则会引发 NumberFormatException 类型的异常:
     * 1. 第一个参数为null或长度为零的字符串。
     * 2. 进制数小于 Character.MIN_RADIX[2] 或大于 Character.MAX_RADIX[36]。
     * 3. 字符串的任何字符都不是指定进制的数字,除非第一个字符可以是减号'-'('\u002D')或加号'+'('\u002B'),前提是字符串长度大于 1。
     * 4. 字符串表示的值不是 int 类型的值。
     *
     * 例子:
     * 	parseInt("0", 10) returns 0
     * 	parseInt("473", 10) returns 473
     * 	parseInt("+42", 10) returns 42
     * 	parseInt("-0", 10) returns 0
     * 	parseInt("-FF", 16) returns -255
     * 	parseInt("1100110", 2) returns 102
     * 	parseInt("2147483647", 10) returns 2147483647
     * 	parseInt("-2147483648", 10) returns -2147483648
     * 	parseInt("2147483648", 10) throws a NumberFormatException
     * 	parseInt("99", 8) throws a NumberFormatException
     * 	parseInt("Kona", 10) throws a NumberFormatException
     * 	parseInt("Kona", 27) returns 411787
     *
     * @param   s  包含要解析的整数的字符串
     * @param   radix  解析 s 时要使用的进制
     * @return  字符串参数以指定的进制数表示的整数。
     * @exception  NumberFormatException 如果 String 不包含可解析的 int
     */
    public static int parseInt(String s, int radix) throws NumberFormatException {
        /*
         * 警告:在初始化 IntegerCache 之前的 VM 初始化期间,可能会提前调用此方法。 必须注意不要使用 valueOf 方法
         */

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

        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");
        }

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

        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);

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

	/**
     * 将字符串参数解析为有符号十进制整数。
     * 字符串中的字符必须都是十进制数字,
     * 除了第一个字符可以是ASCII减号'-'('\u002D')表示负值或ASCII加号'+'('\u002B')表示正值。
     * 返回结果整数值,就像进制数为10作为 parseInt(String,int) 方法的参数一样。
     *
     * @param   s  包含要解析的 int 表示形式的 String
     * @return  由十进制参数表示的整数值。
     * @exception  NumberFormatException 如果字符串不包含可解析的整数。
     */
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

  1. 返回值 int
  2. parseInt(String s) 调用 parseInt(String s, 10) 这个方法
  3. VM 初始化期间,调用 parseInt 不要使用 valueOf
  4. 进制数支持最小2,最大36
  5. NumberFormatException 几种异常情况

# 1.2 例子

public class Test {

    public static void main(String[] args) {
        String string = "1234";
        int n1 = Integer.parseInt(string);
        int n2 = Integer.parseInt(string);
        System.out.println("n1==n2:" + (n1 == n2));
    }

}
1
2
3
4
5
6
7
8
9
10

# 1.3 异常

源码的注释有说明,如果入参为null或长度为0字符串,则会抛出 NumberFormatException

System.out.println(Integer.parseInt(null));
1

System.out.println(Integer.parseInt(""));
1

如果传入长度非0的空字符串呢?

System.out.println(Integer.parseInt("  "));
1

可见,也是抛出 NumberFormatException

# 二:valueOf

# 2.1 源码

package java.lang;

public final class Integer extends Number implements Comparable<Integer> {

	/**
     * 返回一个表示指定 int 值的 Integer 实例。 
     * 如果不需要新的 Integer 实例,则通常应优先使用此方法而不是构造函数 Integer(int),
     * 因为此方法可能会通过缓存频繁请求的值来显著提高空间和时间性能。
     * 此方法将始终缓存 -128 到 127(含)范围内的值
     *
     * @param  i 一个 int 值
     * @return 表示 i 的 Integer 实例。
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    /**
     * 返回一个 Integer 对象,该对象包含指定 String 的值。
     * 该参数被解释为表示一个带符号的十进制整数,就像将该参数提供给 parseInt(String) 方法一样。
     * 结果是一个表示字符串指定的整数值的 Integer 对象。
     *
     * 换句话说,此方法返回一个等于以下值的 Integer 对象:
     *
     * 	new Integer(Integer.parseInt(s))
     *
     * @param   s  要解析的字符串
     * @return  一个 Integer 对象,保存由字符串参数表示的值。
     * @exception  NumberFormatException  如果字符串不能被解析为整数。
     */
    public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

  1. 可以发现最终调用的是 parseInt(String s, 10) 这个方法
  2. Integer.valueOf具有缓存作用

# 1.2 例子

public class Test {

    public static void main(String[] args) {
        Integer n1 = Integer.parseInt("100");
        Integer n2 = Integer.parseInt("100");
        Integer n3 = Integer.parseInt("200");
        Integer n4 = Integer.parseInt("200");
        System.out.println("n1==n2:" + (n1 == n2));
        System.out.println("n3==n4:" + (n3 == n4));
    }

}
1
2
3
4
5
6
7
8
9
10
11
12

# 三:小结

综上所述,一般用 Integer.parseInt(str),除非需要返回 Integer 类型,不然还要封装拆箱,性能多少会耗费些。

最后更新: 5/9/2022, 11:16:58 AM