java源碼學習(二)Integer


Integer類包含了一個原始基本類型int。Integer屬性中就一個屬性,它的類型就是int。

此外,這個類還提供了幾個把int轉成String和把String轉成int的方法,同樣也提供了其它跟int相關處理的常量和方法。

一、定義

public final class Integer extends Number implements Comparable<Integer>{}

從該類的聲明中我們可以看出Integer是final類型的,表示該類不能被繼承,同時該類繼承了Number類;
並實現了接口 Comparable

Number類如下:

public abstract class Number implements java.io.Serializable {

    public abstract int intValue();

    public abstract long longValue();

    public abstract float floatValue();

    public abstract double doubleValue();

    public byte byteValue() {
        return (byte)intValue();
    }

    public short shortValue() {
        return (short)intValue();
    }

    private static final long serialVersionUID = -8742448824652078965L;
}

Integer繼承了Number類,所以該類可以調用longValue、floatValue、doubleValue等系列方法返回對應的類型的值。

二、屬性

1. 私有屬性

private final int value;
private static final long serialVersionUID = 1360826667806852920L;

value屬性就是Integer對象中真正保存int值的

2. 其它屬性

public static final int   MIN_VALUE = 0x80000000;

public static final int   MAX_VALUE = 0x7fffffff;

public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

public static final int SIZE = 32;

public static final int BYTES = SIZE / Byte.SIZE;

定義靜態常量,Integer的最小值(-231),最大值(231-1)
TYPE int的Class實例
SIZE 用來以二進制補碼形式表示 int 值的比特位數
BYTES 用來以二進制補碼形式表示 int 值的字節數。1.8以后才有

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'
};

數值表示成字符串,所要用到的所有字符,這邊就能看到最多能表示成36進制

三、方法

1. 構造方法和valueOf方法

Integer提供了兩個構造方法:

//構造一個新分配的 Integer 對象,它表示指定的 int 值。
public Integer(int value) {
    this.value = value;
}

//構造一個新分配的 Integer 對象,它表示 String 參數所指示的 int 值。
public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
}

首先看一段代碼反編譯前后對比:

public class IntegerTest {
    public static void main(String[] args) {
        Integer i = new Integer(10);
        i = 5;
    }
}
public class IntegerTest
{

    public IntegerTest()
    {
    }

    public static void main(String args[])
    {
        Integer i = new Integer(10);
        i = Integer.valueOf(5);
    }
}

我們來看看valueOf方法

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

以上是valueOf方法的實現細節。通常情況下,IntegerCache.low=-128,IntegerCache.high=127(除非顯示聲明java.lang.Integer.IntegerCache.high的值),Integer中有一段動態代碼塊,該部分內容會在Integer類被加載的時候就執行。

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;
    }

也就是說,當Integer被加載時,就新建了-128到127的所有數字並存放在Integer數組cache中。

再回到valueOf代碼,可以得出結論。當調用valueOf方法(包括后面會提到的重載的參數類型包含String的valueOf方法)時,如果參數的值在-127到128之間,則直接從緩存中返回一個已經存在的對象。如果參數的值不在這個范圍內,則new一個Integer對象返回。

所以,當把一個int變量轉成Integer的時候(或者新建一個Integer的時候),建議使用valueOf方法來代替構造函數。或者直接使用Integer i = 100;編譯器會轉成Integer s = Integer.valueOf(10000);

2. 轉字符串

首先看一下,轉字符串都有哪些方法:

String  toString()
static String   toString(int i)
static String   toString(int i, int radix)
static String   toBinaryString(int i)
static String   toHexString(int i)
static String   toOctalString(int i)
static String   toUnsignedString(int i)
static String   toUnsignedString(int i, int radix)

public String toString() {
	return toString(value);
}

我們看toString(int i)方法

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);
}

如果i 是Integer.MIN_VALUE,也就是整型的最小值,直接返回"-2147483648",但為什么需要這個判斷呢?

由於下面

int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);

我們看stringSize方法

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;
}

此方法實現獲取一個正整數的位數,利用sizeTable(定義位數所對應的最大值),循環依次比較,小於當前位數的最大值,則該整數的位數就是當前sizeTable下標+1
舉個例子,若x=2016,因為x大於9,99,999,小於9999,此時9999 所在的sizeTable下表為3,故最后返回4
局部性原理之空間局部性:sizeTable為數組,存儲在相鄰的位置,cpu一次加載一個塊數據數據到cache中(多個數組數據),此后訪問sizeTable 不需要訪問內存。基於范圍的查找,是很實用的設計技術。

然后所有整數的字符長度就可以算出來了,int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);,負數就算整數去正的字符長度+1,加上的是-,也就是有一位存的是負號

stringSize(-i) -i進行轉換是,若i=Integer.MIN_VALUE=-2147483648,則-i=2147483648,而整數最大值為2147483647,則轉的時候無法賦值,這就解釋了為什么要加那個判斷

Integer result = -(Integer.MIN_VALUE);程序運行結果為result = -2147483648.

再看getChars(i, size, buf);:

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
	// 每次循環過后,都會將i中的走后兩位保存到字符數組buf中的最后兩位中,讀者可以將數字i設置為12345678測試一下,
	//第一次循環結束之后,buf[7] = 8,buf[6]=7。第二次循環結束之后,buf[5] = 6,buf[4] = 5。
	while (i >= 65536) {
		q = i / 100;
		// really: r = i - (q * 100);
		r = i - ((q << 6) + (q << 5) + (q << 2));
		i = q;
		//取DigitOnes[r]的目的其實取數字r%10的結果
		buf [--charPos] = DigitOnes[r];
		//取DigitTens[r]的目的其實是取數字r/10的結果
		buf [--charPos] = DigitTens[r];
	}

	// Fall thru to fast mode for smaller numbers
	// assert(i <= 65536, i);
	//循環將其他數字存入字符數組中空余位置
	for (;;) {
		//這里其實就是除以10。取數52429和16+3的原因在后文分析。
		q = (i * 52429) >>> (16+3);
		r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
		//將數字i的最后一位存入字符數組,
		//還是12345678那個例子,這個for循環第一次結束后,buf[3]=4。
		buf [--charPos] = digits [r];
		i = q;
		//for循環結束后,buf內容為“12345678”;
		if (i == 0) break;
	}
	if (sign != 0) {
		buf [--charPos] = sign;
	}
}

//100以下的數,DigitTens十位數上的數字,DigitOnes為個位數的數字,如86 =DigitTens[86]+ DigitOnes[86] = '8' + '6' = 86

//100以內的數字除以10的結果(取整)
final static char [] DigitTens = {
	'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
	'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
	'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
	'3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
	'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
	'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
	'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
	'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
	'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
	'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
	} ;

//100以內的數字對10取模的結果
final static char [] DigitOnes = {
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	} ;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));

r= i - (q * (26 + 25 + 22)) = i - (q * 100);

為什么小於65536,用下面的方法速度比較快?

移位的效率比直接乘除的效率要高
乘法的效率比除法的效率要高

	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;
	}

q = (i * 52429) >>> (16+3) = (i * 52429) / 524288; 那么就相當於 q = i * 0.1= i /10,這樣通過乘法和向右以為的組合的形式代替了除法,能提高效率。

再來回答上面兩個問題中,部分一和部分二中最大的區別就是部分一代碼使用了除法,第二部分只使用了乘法和移位。因為乘法和移位的效率都要比除法高,所以第二部分單獨使用了乘法加移位的方式來提高效率。那么為什么不都使用乘法加移位的形式呢?為什么大於num1(65536)的數字要使用除法呢?原因是int型變量最大不能超過(2^31-1)。如果使用一個太大的數字進行乘法加移位運算很容易導致溢出。那么為什么是65536這個數字呢?第二階段用到的乘法的數字和移位的位數又是怎么來的呢?

使用num1,num2,num3三個變量代替源代碼中的數字,便於后面分析使用num1=65536 num2=52429 num3=16+3=19

既然我們要使用q = (i * num2) >>> (num3);的形式使用乘法和移位代替除法,那么n和m就要有這樣的關系:

num2= (2^num3 /10 +1)

只有這樣才能保證(i * num2) >>> (num3)結果接近於0.1。

我們看下數據:

2^10=1024, 103/1024=0.1005859375
2^11=2048, 205/2048=0.10009765625
2^12=4096, 410/4096=0.10009765625
2^13=8192, 820/8192=0.10009765625
2^14=16384, 1639/16384=0.10003662109375
2^15=32768, 3277/32768=0.100006103515625
2^16=65536, 6554/65536=0.100006103515625
2^17=131072, 13108/131072=0.100006103515625
2^18=262144, 26215/262144=0.10000228881835938
2^19=524288, 52429/524288=0.10000038146972656
2^20=1048576, 104858/1048576=0.1000003815
2^21=2097152, 209716/2097152 = 0.1000003815
2^22= 4194304, 419431/4194304= 0.1000001431

超過22的數字我就不列舉了,因為如果num3越大,就會要求i比較小,因為必須保證(i * num2) >>> (num3)的過程不會因為溢出而導致數據不准確。那么是怎么敲定num1=65536,num2= 524288, num3=19的呢? 這三個數字之間是有這樣一個操作的:

(num1* num2)>>> num3

因為要保證該操作不能因為溢出導致數據不准確,所以num1和num2就相互約束。兩個數的乘積是有一定范圍的,不成超過這個范圍,所以,num1增大,num2就要隨之減小。

覺得有以下幾個原因:

52429/524288=0.10000038146972656精度足夠高
下一個精度較高的m和n的組合是419431和22。2^31/2^22 = 2^9 = 512。512這個數字實在是太小了。65536正好是2^16,一個整數占4個字節。65536正好占了2個字節,選定這樣一個數字有利於CPU訪問數據。

不知道有沒有人發現,其實65536* 52429是超過了int的最大值的,一旦超過就要溢出,那么為什么還能保證(num1* num2)>>> num3能得到正確的結果呢?

這和>>>有關,因為>>>表示無符號右移,他會在忽略符號位,空位都以0補齊。

一個有符號的整數能表示的范圍是-2147483648至2147483647,但是無符號的整數能表示的范圍就是0-4,294,967,296(2^32),所以,只要保證num2*num3的值不超過2^32次方就可以了。65536是2^16,52429正好小於2^16,所以,他們的乘積在無符號向右移位就能保證數字的准確性。

getChars使用了的體系結構知識:

1.乘法比除法高效:q = ( i * 52429) >>> (16+3); => 約等於q0.1,但i52429是整數乘法器,結合位移避免除法。

2.重復利用計算結果:在獲取r(i%100)時,充分利用了除法的結果,結合位移避免重復計算。

3.位移比乘法高效:r = i – (( q << 6) + ( q << 5) + ( q << 2)); = >等價於r = i – (q * 100);

4.局部性原理之空間局部性

(1).buf[–charPos] =DigitOnes[r];buf[–charPos] =DigitTens[r];通過查找數組,實現快速訪問,避免除法計算

(2).buf [–charPos ] = digits [ r];

return new String(buf, true)

這里用到了一個String中提供的保護類型構造函數,關於此函數請查看String源碼分析,該函數比使用其他的構造函數有更好的性能。

再看看轉換成任意進制字符串:

public static String toString(int i, int radix) {

	//radix 進制數2-32,超出則默認為10進制
	if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
		radix = 10;

	/* Use the faster version */
	if (radix == 10) {
		return toString(i);//專用處理轉十進制字符串
	}

	char buf[] = new char[33];//33長度,int32個字節,加上負號
	boolean negative = (i < 0);
	int charPos = 32;

	// i 統一變負數
	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));
}

上面的方法用於把整形數轉成指定radix的 進制數字符串

這邊提供了轉換為2、8、16進制快捷入口

public static String toHexString(int i) {
    return toUnsignedString(i, 4);
}

public static String toOctalString(int i) {
    return toUnsignedString(i, 3);
}

public static String toBinaryString(int i) {
    return toUnsignedString(i, 1);
}

private static String toUnsignedString(int i, int shift) {
    char[] buf = new char[32];
    int charPos = 32;
    int radix = 1 << shift;
    int mask = radix - 1;
    do {
    	buf[--charPos] = digits[i & mask];
    	i >>>= shift;
    } while (i != 0);

    return new String(buf, charPos, (32 - charPos));
}

位運算

運算符 運算符 示例 說明
& 位與 x&y 把x和y按位求與
~ 位非 ~x 把x按位求非
^ 位異或 x^y 把x和y按位求異或
>> 右移 x>>y 把x的各位右移y位
<< 左移 x<<y 把x的各位左移y位
>>> 右移 x>>>y 把x的各位右移y位,左邊填0

最后總結一下Integer轉string:

所以,一個Integer對象有很多方法能夠將值轉成String類型。除了上面提到的一系列方法外,一般在要使用String的時候,很多人願意使用如下形式:

Integer s = new Integer(199);
System.out.println(s + "");

老規矩,反編譯看看怎么實現的:

Integer s = new Integer(199);
System.out.println((new StringBuilder()).append(s).append("").toString());

筆者使用JMH進行了測試,結果證明方法效率更高。

3. 字符串轉Integer

首先看一下,字符串轉Integer都有哪些方法:

public static int parseInt(String s, int radix) throws NumberFormatException
public static int parseInt(String s) throws NumberFormatException
public static int parseUnsignedInt(String s, int radix) throws NumberFormatException
public static int parseUnsignedInt(String s) throws NumberFormatException

public static Integer valueOf(String s, int radix) throws NumberFormatException
public static Integer valueOf(String s) throws NumberFormatException

public static Integer getInteger(String nm)
public static Integer getInteger(String nm, int val)
public static Integer getInteger(String nm, Integer val)
public static Integer decode(String nm) throws NumberFormatException
public static Integer valueOf(String s)
public static Integer valueOf(String s, int radix)

所有將String轉成Integer的方法都是基於parseInt方法實現的。簡單看一下以上部分方法的調用棧。

getInteger(String nm) ---> getInteger(nm, null);--->Integer.decode()--->Integer.valueOf()--->parseInt()

getInteger的具體實現細節如下:

public static Integer getInteger(String nm, Integer val) {
        String v = null;
        try {
            v = System.getProperty(nm);
        } catch (IllegalArgumentException | NullPointerException e) {
        }
        if (v != null) {
            try {
                return Integer.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        return val;
    }

先按照nm作為key從系統配置中取出值,然后調用Integer.decode方法將其轉換成整數並返回。

decode

public static Integer decode(String nm) throws NumberFormatException

該方法的作用是將 String 解碼為 Integer。接受十進制、十六進制和八進制數字。

根據要解碼的 String(mn)的形式轉成不同進制的數字。 mn由三部分組成:符號、基數說明符和字符序列。 —0X123中-是符號位,0X是基數說明符(0表示八進制,0x,0X,#表示十六進制,什么都不寫則表示十進制),123是數字字符序列。

使用例子舉例如下:

Integer DecimalI = Integer.decode("+10");
Integer OctI = Integer.decode("-010");
Integer HexI = Integer.decode("-0x10");
Integer HexI1 = Integer.decode("#10");
System.out.println(DecimalI);
System.out.println(OctI);
System.out.println(HexI);
System.out.println(HexI1);
//10 -8 -16 16

decode方法的具體實現也比較簡單,首先就是判斷String類型的參數mn是否以(+/—)符號開頭。然后再依次判斷是否以”0x”、“#”、“0”開頭,確定基數說明符的值。然后將字符串mn進行截取,只保留其中純數字部分。在用截取后的純數字和基數調用valueOf(String s, int radix)方法並返回其值。

valueOf

public static Integer valueOf(String s) throws NumberFormatException 
public static int parseInt(String s, int radix) throws NumberFormatException

返回一個 Integer 對象。如果指定第二個參數radix,將第一個參數解釋為用第二個參數指定的基數表示的有符號整數。如果沒指定則按照十進制進行處理。

該方法實現非常簡單:

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));
}

主要用到了兩個方法,parseInt(String s, int radix)和valueOf(int i)方法。前面已經講過valueOf方法會檢查參數內容是否在-127到128之間,如果是則直接返回。否則才會新建一個對象。

//字符串轉十進制數
public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s,10);
}
public static int parseInt(String s, int radix) throws NumberFormatException

使用第二個參數指定的基數(如果沒指定,則按照十進制處理),將字符串參數解析為有符號的整數。除了第一個字符可以是用來表示負值的 ASCII 減號 ‘-‘ (‘\u002D’)外,字符串中的字符必須都是指定基數的數字(通過 Character.digit(char, int) 是否返回一個負值確定)。返回得到的整數值。

如果發生以下任意一種情況,則拋出一個 NumberFormatException 類型的異常:

第一個參數為 null 或一個長度為零的字符串。

基數小於 Character.MIN_RADIX 或者大於 Character.MAX_RADIX。

假如字符串的長度超過 1,那么除了第一個字符可以是減號 ‘-‘ (‘u002D’) 外,字符串中存在任意不是由指定基數的數字表示的字符.

字符串表示的值不是 int 類型的值。

實現的一些例子:

  • parseInt("0", 10) returns 0
  • parseInt("473", 10) returns 473
  • parseInt("+42", 10) returns 42
  • parseInt("-0", 10) returns 0
  • parseInt("-FF", 16) returns -255
  • parseInt("1100110", 2) returns 102
  • parseInt("2147483647", 10) returns 2147483647
  • parseInt("-2147483648", 10) returns -2147483648
  • parseInt("2147483648", 10) throws a NumberFormatException
  • parseInt("99", 8) throws a NumberFormatException
  • parseInt("Kona", 10) throws a NumberFormatException
  • parseInt("Kona", 27) returns 411787
public static int parseInt(String s, int radix)
			throws NumberFormatException
{
	/*
	 * WARNING: This method may be invoked early during VM initialization
	 * before IntegerCache is initialized. Care must be taken to not use
	 * the valueOf method.
	 */
	// 這個方法映射在IntegerCache初始化之前
	// 輸入參數的校驗,錯誤拋出異常
	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;
}

主要思想其實也很好理解。
“12345”按照十進制轉成12345的方法其實就是以下方式: ((1*10)+2)*10)+3)*10+4)*10+5 具體的如何依次取出“12345”中的每一個字符並將起轉成不同進制int類型則是Character.digit方法實現的,這里就不深入講解了。

總結:
上面列舉了很多能夠將String轉成Integer的方法。那么他們之間有哪些區別,又該如何選擇呢?

parseInt方法返回的是基本類型int

其他的方法返回的是Integer

valueOf(String)方法會調用valueOf(int)方法。

如果只需要返回一個基本類型,而不需要一個對象,可以直接使用Integert.parseInt("123");

如果需要一個對象,那么建議使用valueOf(),因為該方法可以借助緩存帶來的好處。

如果和進制有關,那么就是用decode方法。

如果是從系統配置中取值,那么就是用getInteger

4. 其它方法

public int compareTo(Integer anotherInteger)
public static int compare(int x, int y)
public static int compareUnsigned(int x, int y)
public static long toUnsignedLong(int x) jdk1.8
public static int divideUnsigned(int dividend, int divisor) jdk1.8
public static int remainderUnsigned(int dividend, int divisor) jdk1.8

public static int sum(int a, int b) jdk1.8
public static int max(int a, int b) jdk1.8
public static int min(int a, int b) jdk1.8

在看是介紹Interger的類定義的時候介紹過,Integer類實現了Comparable 接口,所以Integer對象可以和另外一個Integer對象進行比較。

public int compareTo(Integer anotherInteger) {
    return compare(this.value, anotherInteger.value);
}

public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

代碼實現比較簡單,就是拿出其中的int類型的value進行比較。

5. 參考資料

http://www.hollischuang.com/archives/1058


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM