Java源码阅读笔记之Integer

Integer的基本实现
Integer的使用
Integer封装的操作

Integer的基本实现

Integer是对原生基本类型int的封装，其定义value来存储值和一些用于描述int的信息

`````` int value;//int
int SIZE = 32;//1位正负标识+31位数据
int BYTES = SIZE / Byte.SIZE;//所占字节
int   MIN_VALUE = 0x80000000;//最小值，32个1
int   MAX_VALUE = 0x7fffffff;//最大值，0+31个1``````

``````    /**
* @deprecated
* It is rarely appropriate to use this constructor. The static factory
* {@link #valueOf(int)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
public Integer(int value) {
this.value = value;
}

/**
* @deprecated
* It is rarely appropriate to use this constructor.
* Use {@link #parseInt(String)} to convert a string to a
* {@code int} primitive, or use {@link #valueOf(String)}
* to convert a string to an {@code Integer} object.
*/
@Deprecated(since="9")
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}``````

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

//----------------------String入参------------------
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}

public static Integer valueOf(String s, int radix) throws NumberFormatException {
}``````
• int入参

• String入参

IntegerCache
``````    //The cache is initialized on first usage.
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;
//The size of the cache may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
String integerCacheHighPropValue =
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() {}
}``````

IntegerCache是一个私有静态内部类该类内部定义了一个数组Integer cache[]，数组内的数据由-128起始，默认至127为止(byte的范围)

-XX:AutoBoxCacheMax=<size>来设置其大小

JDK的源码中，被@HotSpotIntrinsicCandidate标注的方法，在HotSpot中都有一套高效的实现，该高效实现基于CPU指令，运行时，HotSpot维护的高效实现会替代JDK的源码实现，从而获得更高的效率。

parseInt
``````    public static int parseInt(String s, int radix)
throws NumberFormatException
{
...

boolean negative = false;//正负标识
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;

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++;
}
//转化逻辑
int multmin = limit / radix;
int result = 0;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s);
}
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s);
}
}

static final 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'
};``````

parseInt的转化逻辑为：

• 取出digit，确定进制后转化的int数
• 通过result -= digit;把当前的数据加入result

return negative ? result : -result;

Integer的使用

``````   int a = 5;
Integer w = 6;
Integer test = Integer.valueOf(w);
int testP = Integer.valueOf(a);``````

• int a = 5

0: iconst_5
1: istore_1

• Integer w = 6
2: bipush 6
4: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
7: astore_2

• Integer test = Integer.valueOf(w)
9: invokevirtual #3 // Method java/lang/Integer.intValue:()I
12: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
15: astore_3

• int testP = Integer.valueOf(a)
17: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
20: invokevirtual #3 // Method java/lang/Integer.intValue:()I

Integer封装的操作

Object虚函数的实现

Object虚函数的实现

``````    public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}

public static int hashCode(int value) {
return value;
}

public static String toString(int i) {
int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[size * 2];
StringUTF16.getChars(i, size, buf);
return new String(buf, UTF16);
}
}``````
• equals

• hashCode

hashCode返回的就是一个int值，故直接使用value本身

• toString

``````    public byte byteValue() {
return (byte)value;
}

public double doubleValue() {
return (double)value;
}

public float floatValue() {
return (float)value;
}

public int intValue() {
return value;
}

public long longValue() {
return (long)value;
}

public short shortValue() {
return (short)value;
}``````

``````    //左侧
public static int numberOfLeadingZeros(int i) {
if (i <= 0)
return i == 0 ? 32 : 0;
int n = 31;
if (i >= 1 << 16) { n -= 16; i >>>= 16; }
if (i >= 1 <<  8) { n -=  8; i >>>=  8; }
if (i >= 1 <<  4) { n -=  4; i >>>=  4; }
if (i >= 1 <<  2) { n -=  2; i >>>=  2; }
return n - (i >>> 1);
}

//右侧
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}``````

1 负数1标识，左侧无0，0全为0，直接返回32(int为32位)
2 通过1 << 16判断，判断条件为是否比它大，左边16位是否全为0，决定接下来操作左或右半边
3 再通过i << 8，4，2，1折半再折半计算出不为0的数字的位置，从而得出0的数量

• 右侧：numberOfTrailingZeros

``````    public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}``````
• 0x5 = 0101，通过做&运算记录双数位的数据情况

0x3 = 0011，通过做&运算记录后两位的数据情况
0x0f = 0000 1111，通过做&运算记录后四位的数据情况

• 1 int的二进制形式的可能有 00,01,10,11

2 经过第一步计算，记录了以两位数为单位的1的数量

1011 - 0101 = 0110
0001 + 0010 = 0011(1011有三个1)
3 i + (i >>> 4)，i + (i >>> 8)，i + (i >>> 16)分别把得到的上一步计算的结果整合计算

``````    public static int rotateLeft(int i, int distance) {
return (i << distance) | (i >>> -distance);
}

public static int rotateRight(int i, int distance) {
return (i >>> distance) | (i << -distance);
}``````
• 移动

• -distance表示移动-distance负数的表现形式int截取5位，long截取6位，如-1为32个1，截取5位为1 1111，为31，也就是不算位移，移动的“路程”是32，正好把移出的数据再补回补0的地方

``````    public static int reverseBytes(int i) {
return (i << 24)            |
((i & 0xff00) << 8)  |
((i >>> 8) & 0xff00) |
(i >>> 24);
}

public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;

return reverseBytes(i);
}``````
• 按字节置换：reverseBytes

i << 24与i >>> 24做 | 运算得到最左右两边的置换
0xff00二进制形式为1111 1111 0000 0000

• 按位置换：reverse

1 使用01来记录两位二进制中的一位，再通过移动记录另一位，做 | 运算的会把两位的二进制数交换位置
2 通过0011来交换四位中的前两位和后两位
3 通过0000 1111来交换前四位和后四位
4 通过前三步实现交换每8位的循序，再通过按字节置换交换全部的顺序

后话

Integer中还有关于

``````    static final byte[] 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',
} ;

static final byte[] 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',
} ;``````