parseint返回int,valueof返回integer对象:前者拆箱,后者装箱;null时parseint抛numberformatexception,valueof抛nullpointerexception;泛型场景必须用valueof,-128~127范围复用缓存。

parseInt 会直接返回 int,valueOf 返回的是 Integer 对象
这是最根本的区别:一个拆箱,一个装箱。比如 Integer.parseInt("123") 返回原始类型 int,而 Integer.valueOf("123") 返回的是堆上的 Integer 实例。
实际影响在于自动装箱/拆箱行为和空指针风险:
-
parseInt在遇到 null 或非数字字符串时抛NumberFormatException,但不会 NPE -
valueOf同样抛NumberFormatException,但如果传入 null,会直接触发NullPointerException - 在集合操作(如
List<integer></integer>)或泛型上下文中,必须用valueOf—— 因为泛型不接受基本类型 - 频繁调用
valueOf且数值在 -128~127 范围内时,会复用缓存对象;超出范围则每次新建实例
valueOf 其实内部调用了 parseInt,但多了一层包装逻辑
看 JDK 源码就知道:Integer.valueOf(String) 底层就是先调 parseInt(s, 10),再用结果构造 Integer 对象(或从缓存取)。所以性能上 parseInt 略快,但差异微乎其微,除非在超高频循环里。
关键点在于异常处理路径一致,但 valueOf 多一次对象创建开销:
立即学习“Java免费学习笔记(深入)”;
- 如果只是做计算、赋值给
int变量,用parseInt更直接 - 如果要放进
Map<string integer></string>或作为方法参数(接收Integer),别硬转int再塞进去,直接用valueOf - 注意:
Integer.valueOf("123") == Integer.valueOf("123")在 -128~127 成立,但==比较对象引用,不要依赖这个做逻辑判断
别把 parseInt 当万能转换器,它不支持带符号的十六进制字符串
parseInt 默认按十进制解析,想转十六进制得显式传进制参数。比如 "0xFF" 这种带 0x 前缀的字符串,Integer.parseInt("0xFF", 16) 会失败,因为前缀不是合法十六进制字符 —— 它只认纯数字+字母(a-f/A-F)。
常见误用场景:
- 直接传
"0xFF"给parseInt→ 抛NumberFormatException - 忘了删前缀,写成
parseInt("0xFF".substring(2), 16)却没判空或长度 → 空指针或越界 - 混淆
Integer.decode("0xFF"):这个才支持0x、0X、#前缀,但代价是额外解析逻辑,且同样可能抛异常
valueOf 的重载版本容易被忽略:支持进制参数,但 parseInt 更常用
Integer.valueOf(String, int radix) 和 parseInt 一样支持进制参数,比如 Integer.valueOf("FF", 16) 是合法的。但它和 parseInt 的区别依然在返回类型 —— 一个是 Integer,一个是 int。
真正要注意的是:这两个方法对进制范围有严格限制(2~36),超出就抛 IllegalArgumentException,不是 NumberFormatException:
- 写
parseInt("10", 37)→ 报错java.lang.IllegalArgumentException: radix 37 out of range - 很多人只记得捕获
NumberFormatException,漏了这个异常类型,导致线上 crash - 如果输入进制来自配置或用户输入,务必先校验是否在 [2, 36] 区间内
最常被绕过的细节是:null 输入对 valueOf 是 NPE,对 parseInt 是 NumberFormatException;还有进制参数的异常类型不统一。这些边界在单元测试里很容易漏掉。










