上節我們介紹過JDK源碼-Float類
本節我們介紹Integer類,Integer 類在對象中包裝了一個基本類型 int 的值。Integer 類對象包含一個 int 類型的字段。此外,該類提供了多個方法,能在 int 類型和 String 類型之間互相轉換,還提供了處理 int 類型時非常有用的其他一些常量和方法。
一、實現方法
Integer類是基本類型int的包裝類,繼承了Number類,並且實現了Comparable接口
public final class Integer extends Number implements Comparable<Integer>
二、構造方法
//構造一個新分配的 Integer 對象,它表示指定的 int 值
public Integer(int value) {
this.value = value;
}
//構造一個新分配的 Integer 對象,它表示 String 參數所指示的 int 值。
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
用來存放Integer對象那int對應的值。
private final int value;
二、常用常量
//值爲 -2^31 的常量,它表示 int 類型能夠表示的最小值
@Native public static final int MIN_VALUE = 0x80000000;
//值爲 2^31-1 的常量,它表示 int 類型能夠表示的最大值
@Native public static final int MAX_VALUE = 0x7fffffff;
//表示基本類型 int 的 Class 實例
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
//所有可能的char字符數組
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
三、常用方法
toString toXXXString 系列
//靜態方法根據指定進制返回一個String,如果基數小於 Character.MIN_RADIX 或者大於 Character.MAX_RADIX,默認設置爲10。如果是負數 第一個符號位負號 '-' ('\u002D'),如果不是負數,將不會有符號剩下的字符表示第一個參數的大小如果大小是0 由字符 '0' ('\u0030') 表示,否則用來表示數值的第一個字符不會是0
public static String toString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
if (radix == 10) {
return toString(i);
}
char buf[] = new char[33];
boolean negative = (i < 0);
int charPos = 32;
if (!negative) {
i = -i;
}
while (i <= -radix) {
buf[charPos--] = digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = digits[-i];
if (negative) {
buf[--charPos] = '-';
}
return new String(buf, charPos, (33 - charPos));
}
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);
}
//靜態方法以十六進制(基數 16)無符號整數形式返回一個整數參數的字符串表示形式
public static String toHexString(int i) {
return toUnsignedString0(i, 4);
}
//靜態方法以八進制(基數 8)無符號整數形式返回一個整數參數的字符串表示形式
public static String toOctalString(int i) {
return toUnsignedString0(i, 3);
}
//靜態方法以二進制(基數 2)無符號整數形式返回一個整數參數的字符串表示形式
public static String toBinaryString(int i) {
return toUnsignedString0(i, 1);
}
//私有方法用於轉換爲無符號形式
private static String toUnsignedString0(int val, int shift) {
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
return new String(buf, true);
}
parseInt方法
//靜態方法使用第二個參數指定的基數(進制),將字符串參數解析爲有符號的整數除了第一個字符可以是用來表示負值的 ASCII 減號 '-' ('\u002D’),加號'+' ('\u002B') 外字符串中的字符必須都是指定基數的數字
public static int parseInt(String s, int radix) throws NumberFormatException
{
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;
}
//靜態方法static int parseInt(String s, int radix) 的十進制簡化形式
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
valueOf方法
核心邏輯在第一個valueOf方法中,因爲IntegerCache緩存了[low,high]值的Integer對象,對於在範圍內的直接從IntegerCache的數組中獲取對應的Integer對象即可,而在範圍外的則需要重新實例化了。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
IntegerCache內部類
IntegerCache是Integer的一個內部類,它包含了int可能值的Integer數組,默認範圍是[-128,127],它不會像Byte類將所有可能值緩存起來,因爲int類型範圍很大,將它們全部緩存起來代價太高,而Byte類型就是從-128到127,一共才256個。所以這裏默認只實例化256個Integer對象,當Integer的值範圍在[-128,127]時則直接從緩存中獲取對應的Integer對象,不必重新實例化。這些緩存值都是靜態且final的,避免重複的實例化和回收。另外我們可以改變這些值緩存的範圍,再啓動JVM時通過-Djava.lang.Integer.IntegerCache.high=xxx就可以改變緩存值的最大值,比如-Djava.lang.Integer.IntegerCache.high=500則會緩存[-128,500]。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
decode方法
decode方法主要作用是解碼字符串轉成Integer型,比如Integer.decode(“11”)的結果爲11;Integer.decode(“0x11”)和Integer.decode("#11")結果都爲17,因爲0x和#開頭的會被處理成十六進制;Integer.decode(“011”)結果爲9,因爲0開頭會被處理成8進制。
public static Integer decode(String nm) throws NumberFormatException {
int radix = 10;
int index = 0;
boolean negative = false;
Integer result;
if (nm.length() == 0)
throw new NumberFormatException("Zero length string");
char firstChar = nm.charAt(0);
if (firstChar == '-') {
negative = true;
index++;
} else if (firstChar == '+')
index++;
if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
index += 2;
radix = 16;
}
else if (nm.startsWith("#", index)) {
index ++;
radix = 16;
}
else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
index ++;
radix = 8;
}
if (nm.startsWith("-", index) || nm.startsWith("+", index))
throw new NumberFormatException("Sign character in wrong position");
try {
result = Integer.valueOf(nm.substring(index), radix);
result = negative ? Integer.valueOf(-result.intValue()) : result;
} catch (NumberFormatException e) {
String constant = negative ? ("-" + nm.substring(index))
: nm.substring(index);
result = Integer.valueOf(constant, radix);
}
return result;
}
XXXValue系列
強制類型轉換的形式,
public byte byteValue() {
return (byte)value;
}
public short shortValue() {
return (short)value;
}
public int intValue() {
return value;
}
public long longValue() {
return (long)value;
}
public float floatValue() {
return (float)value;
}
public double doubleValue() {
return (double)value;
}
hashCode()
直接返回 value 的 int 類型的值。
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
equals(Object obj)
比較是否相同時先判斷是不是Integer類型再比較值。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}