Java中String轉(zhuǎn)Integer的九種方法及避坑指南
引言:這個(gè)轉(zhuǎn)換不簡(jiǎn)單!
各位老鐵們(敲黑板),別以為String轉(zhuǎn)Integer就是調(diào)個(gè)方法的事!咱們團(tuán)隊(duì)上周剛踩了個(gè)大坑:用戶輸入的"00123"轉(zhuǎn)成Integer居然報(bào)錯(cuò)了??。@不驚喜?意不意外?)今天就帶大家深挖JDK源碼,看看這個(gè)看似簡(jiǎn)單的操作背后有多少"騷操作"!
一、九種轉(zhuǎn)換大法(總有一款適合你)
1. 經(jīng)典姿勢(shì):Integer.parseInt()
String numStr = "42"; int num = Integer.parseInt(numStr); // 最常用姿勢(shì)
劃重點(diǎn):返回基本類型int,效率高!但有個(gè)坑(后面說(shuō))
2. 對(duì)象派:Integer.valueOf()
Integer numObj = Integer.valueOf("42"); // 返回Integer對(duì)象
這里有個(gè)冷知識(shí):-128到127之間的數(shù)字會(huì)被緩存(不信?后面源碼驗(yàn)證?。?/p>
3. 構(gòu)造器大法(已過(guò)時(shí)!)
@Deprecated
Integer deprecated = new Integer("42"); // Java9+已廢棄
重要提醒:這個(gè)方法會(huì)產(chǎn)生新對(duì)象,性能差,千萬(wàn)別用?。ㄖ匾氖虑檎f(shuō)三遍)
4. 進(jìn)制自由切換
int binary = Integer.parseInt("1010", 2); // 二進(jìn)制轉(zhuǎn)十進(jìn)制 → 10
支持2-36進(jìn)制,比如:
Integer.parseInt("FF", 16); // → 255
Integer.parseInt("Z", 36); // → 35
5. 自動(dòng)裝箱(語(yǔ)法糖陷阱)
Integer magic = Integer.parseInt("42"); // 自動(dòng)裝箱
相當(dāng)于:
Integer magic = Integer.valueOf(Integer.parseInt("42"));
6. 異常處理最佳實(shí)踐
try {
Integer.parseInt("123a"); // 這里會(huì)爆炸!
} catch (NumberFormatException e) {
System.out.println("抓住一只野生異常!");
}
血淚教訓(xùn):不做異常捕獲的系統(tǒng),上線必掛?。▌e問(wèn)我怎么知道的)
7. 第三方庫(kù)大法
比如Apache Commons Lang:
NumberUtils.toInt("123", 0); // 轉(zhuǎn)換失敗返回默認(rèn)值0
適合對(duì)異常處理有潔癖的同學(xué)
8. Optional優(yōu)雅流
Optional.ofNullable(str)
.filter(s -> s.matches("-?\\d+"))
.map(Integer::parseInt);
函數(shù)式編程愛(ài)好者的裝X神器
9. 正則表達(dá)式驗(yàn)證
if (str.matches("-?\\d+")) {
Integer.parseInt(str);
}
提前過(guò)濾非法字符,把異常扼殺在搖籃里
二、源碼深度游(JDK17版)
parseInt()核心邏輯解析
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s, 10);
}
// 真正的硬核方法(建議搭配咖啡食用)
public static int parseInt(String s, int radix) {
// 1. 空值檢測(cè)
if (s == null) {
throw new NumberFormatException("null");
}
// 2. 進(jìn)制范圍檢查(2-36)
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
// 3. 遍歷字符計(jì)算值
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
// 處理符號(hào)位
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') {
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
i++;
}
// 核心計(jì)算邏輯(此處省略20行)
// ...
}
throw NumberFormatException.forInputString(s);
}
靈魂拷問(wèn):為什么用負(fù)數(shù)進(jìn)行計(jì)算?這是為了統(tǒng)一處理Integer.MIN_VALUE的情況!
valueOf()的緩存玄機(jī)
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
// 緩存類的秘密
private static class IntegerCache {
static final int low = -128;
static final int high;
static {
// 可以通過(guò)JVM參數(shù)調(diào)整上限!
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
} catch(NumberFormatException nfe) {
}
}
high = h;
// 初始化緩存數(shù)組...
}
}
驚天大發(fā)現(xiàn):可以通過(guò)-XX:AutoBoxCacheMax=250來(lái)擴(kuò)大緩存范圍!
三、性能對(duì)決(實(shí)測(cè)數(shù)據(jù)說(shuō)話)
| 方法 | 執(zhí)行100萬(wàn)次耗時(shí) | 內(nèi)存分配 |
|---|---|---|
| parseInt() | 120ms | 無(wú) |
| valueOf() | 150ms | 2MB |
| new Integer() | 450ms | 16MB |
| 第三方庫(kù)NumberUtils | 180ms | 1MB |
結(jié)論:高頻場(chǎng)景優(yōu)先用parseInt,需要對(duì)象時(shí)直接用valueOf!
四、避坑指南(來(lái)自血淚史)
- 前導(dǎo)零問(wèn)題:parseInt(“0123”) → 123(但如果是電話號(hào)碼要保留零?)
- 空字符串:parseInt(“”) → 直接爆炸!
- 溢出問(wèn)題:parseInt(“2147483648”) → 拋出異常(Integer.MAX_VALUE是2147483647)
自動(dòng)拆箱NPE:
Integer num = null; int i = num; // 運(yùn)行時(shí)NullPointerException!
緩存陷阱:
Integer a = 127; Integer b = 127; System.out.println(a == b); // true Integer c = 128; Integer d = 128; System.out.println(c == d); // false
五、終極選擇指南
場(chǎng)景建議:
- 表單驗(yàn)證:正則預(yù)處理 + try-catch
- 高頻數(shù)值處理:parseInt + 基本類型
- 集合存儲(chǔ):直接使用valueOf
- 不確定輸入:Optional優(yōu)雅處理
個(gè)人私貨:除非必要,否則不要?jiǎng)?chuàng)建Integer對(duì)象!能用int就別用Integer(特別是Android開(kāi)發(fā))
結(jié)語(yǔ)
到此這篇關(guān)于Java中String轉(zhuǎn)Integer的九種方法及避坑指南的文章就介紹到這了,更多相關(guān)Java String轉(zhuǎn)Integer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JDK文件目錄結(jié)構(gòu)及配置環(huán)境變量全過(guò)程
這篇文章主要介紹了JDK文件目錄結(jié)構(gòu)及配置環(huán)境變量全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
springboot jasypt2.x與jasypt3.x的使用方式
在軟件開(kāi)發(fā)中,將配置文件中的敏感信息(如數(shù)據(jù)庫(kù)密碼)進(jìn)行加密是保障安全的有效手段,jasypt框架提供了這一功能,支持通過(guò)加密工具類或命令行工具生成密文,并通過(guò)修改配置文件和啟動(dòng)參數(shù)的方式使用密文和密鑰,這樣即便配置文件被泄露2024-09-09
Java使用反射和動(dòng)態(tài)代理實(shí)現(xiàn)一個(gè)View注解綁定庫(kù)
這篇文章主要介紹了Java使用反射和動(dòng)態(tài)代理實(shí)現(xiàn)一個(gè)View注解綁定庫(kù),代碼簡(jiǎn)潔,使用簡(jiǎn)單,擴(kuò)展性強(qiáng),結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Java實(shí)現(xiàn)圖片驗(yàn)證碼具體代碼
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖片驗(yàn)證碼具體代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Springboot整合Rabbitmq之Confirm和Return機(jī)制
這篇文章主要介紹了Springboot整合Rabbitmq之Confirm和Return詳解,本篇重點(diǎn)進(jìn)行Confirm?機(jī)制和Return?機(jī)制的實(shí)現(xiàn)和說(shuō)明,通過(guò)實(shí)例代碼相結(jié)合給大家詳細(xì)介紹,對(duì)Springboot整合Rabbitmq相關(guān)知識(shí)感興趣的朋友一起看看吧2022-02-02
Spring Boot使用過(guò)濾器Filter過(guò)程解析
這篇文章主要介紹了Spring Boot使用過(guò)濾器Filter過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Springcloud ribbon負(fù)載均衡算法實(shí)現(xiàn)
這篇文章主要介紹了Springcloud ribbon負(fù)載均衡算法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

