前面介紹了 java.lang 包下的 Object 類,這是所有類的父類。本篇文章接著介紹該包下的另一個也很常用的類 Integer。
1. Integer 的聲明
public final class Integer extends Number implements Comparable< Integer >{}
Integer 是用 final 聲明的常量類,不能被任何類所繼承。并且 Integer 類繼承了 Number 類和實現(xiàn)了 Comparable 接口。Number 類是一個抽象類,8種基本數(shù)據(jù)類型的包裝類除了Character 和 Boolean 沒有繼承該類外,剩下的都繼承了 Number 類,該類的方法用于各種數(shù)據(jù)類型的轉(zhuǎn)換。Comparable 接口就一個 compareTo 方法,用于元素之間的大小比較,下面會對這些方法詳細(xì)展開介紹。
2. Integer 的主要屬性
int 類型在 Java 中是占據(jù) 4 個字節(jié),所以其可以表示大小的范圍是 -2^31——2^31 -1即 -2147483648——2147483647,我們在用 int 表示數(shù)值時一定不要超出這個范圍了。
3. 構(gòu)造方法 Integer(int)、Integer(String)
public Integer(int var1) {
this.value = var1;
}
對于第二個構(gòu)造方法 Integer(String) 就是將我們輸入的字符串?dāng)?shù)據(jù)轉(zhuǎn)換成整型數(shù)據(jù)。
首先我們必須要知道能轉(zhuǎn)換成整數(shù)的字符串必須分為兩個部分:第一位必須是"+"或者"-",剩下的必須是 0-9 和 a-z 字符
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);//首先調(diào)用parseInt(s,10)方法,其中s表示我們需要轉(zhuǎn)換的字符串,10表示以十進(jìn)制輸出,默認(rèn)也是10進(jìn)制
}
public static int parseInt(String s, int radix) throws NumberFormatException{
//如果轉(zhuǎn)換的字符串如果為null,直接拋出空指針異常
if (s == null) {
throw new NumberFormatException("null");
}
//如果轉(zhuǎn)換的radix(默認(rèn)是10)< 2 則拋出數(shù)字格式異常,因為進(jìn)制最小是 2 進(jìn)制
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
//如果轉(zhuǎn)換的radix(默認(rèn)是10) >36 則拋出數(shù)字格式異常,因為0到9一共10位,a到z一共26位,所以一共36位
//也就是最高只能有36進(jìn)制數(shù)
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();//len是待轉(zhuǎn)換字符串的長度
int limit = -Integer.MAX_VALUE;//limit = -2147483647
int multmin;
int digit;
//如果待轉(zhuǎn)換字符串長度大于 0
if (len > 0) {
char firstChar = s.charAt(0);//獲取待轉(zhuǎn)換字符串的第一個字符
//這里主要用來判斷第一個字符是"+"或者"-",因為這兩個字符的 ASCII碼都小于字符'0'
if (firstChar < '0') {
if (firstChar == '-') {//如果第一個字符是'-'
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')//如果第一個字符是不是 '+',直接拋出異常
throw NumberFormatException.forInputString(s);
if (len == 1) //待轉(zhuǎn)換字符長度是1,不能是單獨(dú)的"+"或者"-",否則拋出異常
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
//通過不斷循環(huán),將字符串除掉第一個字符之后,根據(jù)進(jìn)制不斷相乘在相加得到一個正整數(shù)
//比如 parseInt("2abc",16) = 2*16的3次方+10*16的2次方+11*16+12*1
//parseInt("123",10) = 1*10的2次方+2*10+3*1
while (i < len) {
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 {//如果待轉(zhuǎn)換字符串長度小于等于0,直接拋出異常
throw NumberFormatException.forInputString(s);
}
//根據(jù)第一個字符得到的正負(fù)號,在結(jié)果前面加上符號
return negative ? result : -result;
}
4. toString()、toString(int i)、toString(int i, int radix)
這三個方法重載,能返回一個整型數(shù)據(jù)所表示的字符串形式,其中最后一個方法 toString(int,int) 第二個參數(shù)是表示的進(jìn)制數(shù)。
public String toString() {
return toString(value);
}
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
toString(int) 方法內(nèi)部調(diào)用了 stringSize() 和 getChars() 方法,stringSize() 它是用來計算參數(shù) i 的位數(shù)也就是轉(zhuǎn)成字符串之后的字符串的長度,內(nèi)部結(jié)合一個已經(jīng)初始化好的int類型的數(shù)組sizeTable來完成這個計算。
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
實現(xiàn)的形式很巧妙。注意負(fù)數(shù)包含符號位,所以對于負(fù)數(shù)的位數(shù)是 stringSize(-i) + 1。
再看 getChars 方法:
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q < < 6) + (q < < 5) + (q < < 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) > >> (16+3);
r = i - ((q < < 3) + (q < < 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
i:被初始化的數(shù)字,
index:這個數(shù)字的長度(包含了負(fù)數(shù)的符號“-”),
buf:字符串的容器-一個char型數(shù)組。
第一個if判斷,如果i<0,sign記下它的符號“-”,同時將i轉(zhuǎn)成整數(shù)。下面所有的操作也就只針對整數(shù)了,最后在判斷sign如果不等于零將 sign 的值放在char數(shù)組的首位buf [--charPos] = sign;。
5. 自動拆箱和裝箱
自動拆箱和自動裝箱是 JDK1.5 以后才有的功能,也就是java當(dāng)中眾多的語法糖之一,它的執(zhí)行是在編譯期,會根據(jù)代碼的語法,在生成class文件的時候,決定是否進(jìn)行拆箱和裝箱動作。
①、自動裝箱
我們知道一般創(chuàng)建一個類的對象需要通過 new 關(guān)鍵字,比如:
Object obj = new Object();
但是實際上,對于 Integer 類,我們卻可以直接這樣使用:
Integer a = 128;
為什么可以這樣,通過反編譯工具,我們可以看到,生成的class文件是:
Integer a = Integer.valueOf(128);
我們可以看看 valueOf() 方法
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
其實最后返回的也是通過new Integer() 產(chǎn)生的對象,但是這里要注意前面的一段代碼,當(dāng)i的值 -128 <= i <= 127 返回的是緩存類中的對象,并沒有重新創(chuàng)建一個新的對象,這在通過 equals 進(jìn)行比較的時候我們要注意。
這就是基本數(shù)據(jù)類型的自動裝箱,128是基本數(shù)據(jù)類型,然后被解析成Integer類。
②、自動拆箱
我們將 Integer 類表示的數(shù)據(jù)賦值給基本數(shù)據(jù)類型int,就執(zhí)行了自動拆箱。
Integer a = new Integer(128);
int m = a;
反編譯生成的class文件:
Integer a = new Integer(128);
int m = a.intValue();
簡單來講:自動裝箱就是Integer.valueOf(int i);自動拆箱就是 i.intValue();
6. equals(Object obj)方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
這個方法很簡單,先通過 instanceof 關(guān)鍵字判斷兩個比較對象的關(guān)系,然后將對象強(qiáng)轉(zhuǎn)為 Integer,再通過自動拆箱,轉(zhuǎn)換成兩個基本數(shù)據(jù)類 int,然后通過 == 比較。
7. hashCode() 方法
public int hashCode() {
return value;
}
Integer 類的hashCode 方法也比較簡單,直接返回其 int 類型的數(shù)據(jù)。
8. parseInt(String s) 和 parseInt(String s, int radix) 方法
前面通過 toString(int i) 可以將整型數(shù)據(jù)轉(zhuǎn)換成字符串類型輸出,這里通過 parseInt(String s) 能將字符串轉(zhuǎn)換成整型輸出。
這兩個方法我們在介紹 構(gòu)造函數(shù) Integer(String s) 時已經(jīng)詳細(xì)講解了。
9. compareTo(Integer anotherInteger) 和 compare(int x, int y) 方法
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
compareTo 方法內(nèi)部直接調(diào)用 compare 方法:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
如果 x < y 返回 -1
如果 x == y 返回 0
如果 x > y 返回 1
System.out.println(Integer.compare(1, 2));//-1
System.out.println(Integer.compare(1, 1));//0
System.out.println(Integer.compare(1, 0));//1
10. 小結(jié)
好了,這就是JDK中java.lang.Integer類的源碼解析,隨著JDK的更新,該類應(yīng)該還會有變化,文章也會實時更新。
-
接口
+關(guān)注
關(guān)注
33文章
8526瀏覽量
150863 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6909瀏覽量
88850 -
JAVA
+關(guān)注
關(guān)注
19文章
2960瀏覽量
104565
發(fā)布評論請先 登錄
相關(guān)推薦
評論