Java中valueOf和parseInt的區(qū)別詳解
前言
在編程中,遇到類型轉(zhuǎn)換,好像會經(jīng)常用到 parseInt 和 valueOf,當(dāng)然這里只拿 Integer 類型進(jìn)行陳述,其他類型也是雷同的;
想必有讀者也跟我一樣,經(jīng)常交叉使用這兩個方法,但卻不知道這兩者到底有什么區(qū)別,接下來就來探究一番;
區(qū)別
- Integer.parseInt(s) 的作用就是把字符串 s 解析成有符號基本類型的 int;
- Integer.valueOf(s) 把字符串 s 解析成 Integer 對象類型,返回的對象可以調(diào)用 Integer 中的方法;
接下來,通過源碼進(jìn)行逐一解析;
parseInt
我們首先點(diǎn)進(jìn) parseInt() 方法中,
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s, 10);
}可以看到,這個被我們調(diào)用的 parseInt() 方法返回了一個重載方法:
public static int parseInt(String s, int radix) throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
} else if (radix < 2) {
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
} else if (radix > 36) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
} else {
boolean negative = false;
int i = 0;
int len = s.length();
int limit = -2147483647;
if (len <= 0) {
throw NumberFormatException.forInputString(s);
} else {
char firstChar = s.charAt(0);
if (firstChar < '0') {
if (firstChar == '-') {
negative = true;
limit = -2147483648;
} else if (firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
if (len == 1) {
throw NumberFormatException.forInputString(s);
}
++i;
}
int multmin = limit / radix;
int result;
int digit;
for(result = 0; i < len; result -= digit) {
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
}
return negative ? result : -result;
}
}
}1、首先看到的是,該方法傳入了兩個參數(shù),parseInt(String s, int radix),這個可以根據(jù)被調(diào)用時傳入的參數(shù),return parseInt(s, 10);,盲猜一下,s 就是表示要轉(zhuǎn)換成數(shù)字型的字符串,而 radix 英文是基數(shù)的意思,這里應(yīng)該表示進(jìn)制,即這個傳入的字符串是多少進(jìn)制的,那到底是不是呢,我們接著往下看;
2、這里先是對字符串 s 是否為空,以及 radix 的大小進(jìn)行一個判斷,不符合條件則拋出 NumberFormatException 異常,也就是數(shù)字格式化異常;
if (s == null){
throw new NumberFormatException("null");
} else if (radix < 2) {
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
} else if (radix > 36) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
} else {
3、接著往下,再一次對長度進(jìn)行一個校驗,
int len = s.length();
if (len <= 0) {
throw NumberFormatException.forInputString(s);
} else {
...
}
我在這里只想到了一個能讓它拋出異常的條件,
Integer.parseInt("");運(yùn)行結(jié)果:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
4、接下來會檢測第一個字符是啥,如果是 -,則將 negative 設(shè)置成 true,表示這是個負(fù)數(shù),并且將邊界 limit 設(shè)置成最小邊界;
如果不是 +,則表示該字符既不是數(shù)字,不也是性質(zhì)符號,因此拋出 NumberFormatException 異常;
如果字符串 s 的長度只有1,則表明這是非數(shù)字,不符合要求,也拋出 NumberFormatException 異常;
++i 是因為如果第一位是符號的話,那么在后續(xù)的循環(huán)中追加數(shù)字則直接跳過首位;
char firstChar = s.charAt(0);
if (firstChar < '0') {
if (firstChar == '-') {
negative = true;
limit = -2147483648;
} else if (firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
if (len == 1) {
throw NumberFormatException.forInputString(s);
}
++i;
}
5、根據(jù)進(jìn)制來調(diào)整邊界,以防越界;
int multmin = limit / radix;
6、Character.digit() 用于將字符轉(zhuǎn)為為對應(yīng)進(jìn)制的整數(shù),如果該字符不是進(jìn)制內(nèi)的就返回-1,例如輸入的字符是9,但是進(jìn)制是2,那么就不符合,則會返回-1;
然后就是進(jìn)行計算;
int result;
int digit;
for(result = 0; i < len; result -= digit) {
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
}
7、最后判斷是否為負(fù)數(shù)完成轉(zhuǎn)換;
return negative ? result : -result;
valueOf
照例查看源碼:
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return parseInt(s, radix);
}
public static Integer valueOf(String s) throws NumberFormatException {
return parseInt(s, 10);
}
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
可以看出 valueOf(String s, int radix) 和 valueOf(String s) 都是直接調(diào)用返回了 parseInt 方法,而 valueOf(int i) 則是一個 int 轉(zhuǎn)成 Integer 的自動裝箱;
接下來探究一下 IntegerCache ,可以看出這是 Integer 的成員內(nèi)部類,來看源碼:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
private IntegerCache() {
}
static {
int h = 127;
String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
int size;
if (integerCacheHighPropValue != null) {
try {
size = Integer.parseInt(integerCacheHighPropValue);
size = Math.max(size, 127);
h = Math.min(size, 2147483518);
} catch (NumberFormatException var6) {
}
}
high = h;
VM.initializeFromArchive(Integer.IntegerCache.class);
size = high - -128 + 1;
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = -128;
for(int k = 0; k < c.length; ++k) {
c[k] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
assert high >= 127;
}
}
整體就是初始化一個 IntegerCache.cache 數(shù)組,數(shù)組里面存儲-128到127之間的數(shù)字當(dāng)做是緩存,源碼一開始是分析數(shù)組長度,然后給數(shù)組賦值;
總的來說,三個重構(gòu)的 valueOf() 方法還是大同小異的:
- Integer valueOf(int i):返回一個表示指定的 int 值的 Integer 實(shí)例;
- Integer valueOf(String s):返回保存指定的 String 的值的 Integer 對象;
- Integer valueOf(String s, int radix):返回一個 Integer 對象,該對象中保存了用第二個參數(shù)提供的基數(shù)進(jìn)行解析時從指定的 String 中提取的值;
到此這篇關(guān)于Java中valueOf和parseInt的區(qū)別詳解的文章就介紹到這了,更多相關(guān)valueOf和parseInt的區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中基于注解的代碼生成工具M(jìn)apStruct映射使用詳解
MapStruct?作為一個基于注解的代碼生成工具,為我們提供了一種更加優(yōu)雅、高效的解決方案,本文主要為大家介紹了它的具體使用,感興趣的可以了解下2025-02-02
Java線程池如何實(shí)現(xiàn)精準(zhǔn)控制每秒API請求
這篇文章主要介紹了Java線程池如何實(shí)現(xiàn)精準(zhǔn)控制每秒API請求問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
java將html轉(zhuǎn)成圖片代碼實(shí)例(html2image)
這篇文章主要介紹了java將html轉(zhuǎn)成圖片的相關(guān)資料,在Java開發(fā)中,將HTML轉(zhuǎn)換為圖片可以使用html2image庫,文中通過代碼及圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
Java Web學(xué)習(xí)之Cookie和Session的深入理解
這篇文章主要給大家介紹了關(guān)于Java Web學(xué)習(xí)之Cookie和Session的相關(guān)資料,需要的朋友可以參考下2018-04-04
springboot中websocket簡單實(shí)現(xiàn)
本文主要介紹了springboot中websocket簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01

