After reading the source code for Short, today I will read the source code for the wrapping class Integer.
The cache
Remember the cache from the Short source?
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); MAX_VALUE (Max size integer.max_value) h = math.min (I, integer.max_value - (-low) -1); // Maximum array size is integer.max_value (Max size 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 high must be greater than or equal to 127. } private IntegerCache() {} }Copy the code
It looks a little more complicated than Short, but it actually adds the ability to specify the cache. Why is low always -127 not open? (Negative numbers are rarely guessed, so caching negative numbers is pointless.)
Member variables
public static final int BYTES = SIZE / Byte.SIZE; //4 @Native public static final int SIZE = 32; // There is a primitive annotation @native. Final static int [] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; Final static char [] DigitOnes = {/ / this is an interesting and the use of the following '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'}; 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'}; 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' }; @Native public static final int MAX_VALUE = 0x7fffffff; @Native public static final int MIN_VALUE = 0x80000000;Copy the code
The constructor
public Integer(int value) { this.value = value; } public Integer(String s) throws NumberFormatException {// Short uses Integer parseInt to parse. This. value = parseInt(s, 10); }Copy the code
//pareseInt key code...... 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) {// Decrypt digit = character.digit (S.char (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; .Copy the code
toString
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); getChars(I, size, buf); return new String(buf, true); } 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); q*64+q*32+q*4=q*(64+32+4)=q*100 r = i - ((q << 6) + (q << 5) + (q << 2)); i = q; // If r=45, think of DigitOnes, DigitOnes[--charPos] = DigitOnes[r]; buf [--charPos] = DigitTens[r]; } // Fall thru to fast mode for smaller numbers // assert(i <= 65536, i); for (;;) {// use multiplication instead of division q = (I * 52429) >>> (16+3); / / is approximately equal to the I * (2 ^ 20/10) / 2 ^ 19 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; }}Copy the code
valueOf
// You can pass in the base of the string, Public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); } public static Integer valueOf(String s) throws NumberFormatException {// Return integer.Valueof (parseInt(s, 10)); } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }Copy the code
getInteger
Public static Integer getInteger(String nm) {return getInteger(nm, null); } public static Integer getInteger(String nm, int val) { Integer result = getInteger(nm, null); return (result == null) ? Integer.valueOf(val) : result; } public static Integer getInteger(String nm, Integer val) { String v = null; try { v = System.getProperty(nm); } catch (IllegalArgumentException | NullPointerException e) { } if (v ! = null) {try {// decode, because there are various bases return integer.decode (v); } catch (NumberFormatException e) { } } return val; }Copy the code
contrast
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); } // MIN_VALUE = 0x80000000; public static int compareUnsigned(int x, int y) { return compare(x + MIN_VALUE, y + MIN_VALUE); }Copy the code
Other interesting methods
Public static long toUnsignedLong(int x) {return ((long) x) &0xffff ffffL; Public static int remainderUnsigned(int dividend, int divisor) {// In lieu of tricky code, for now just use long arithmetic. return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor)); } public static int divideUnsigned(int dividend, int divisor) {// In lieu of tricky code, for now just use long arithmetic. return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor)); } / / highest 1 public static int highestOneBit (int I) {/ / HD, Figure 3-1 1001 - > 1111 1111-0111 (binary) I | = (I > > 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); } public static int lowestOneBit(int I) {public static int lowestOneBit(int I) {public static int lowestOneBit(int I); } public static int numberOfLeadingZeros(int I) {if (I == 0) return 32; int n = 1; if (i >>> 16 == 0) { n += 16; i <<= 16; } if (i >>> 24 == 0) { n += 8; i <<= 8; } if (i >>> 28 == 0) { n += 4; i <<= 4; } if (i >>> 30 == 0) { n += 2; i <<= 2; } n -= i >>> 31; return n; } 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); } 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; }Copy the code