1. 类图

Java源码系列-Integer源码:Java源码系列-Integer源码(1)

integer-Class

2. 存储位置

public class IntegerDemoTest { @Test public void newIntegerTest() { Integer a = 3; Integer b = 3; Integer a = 3; <==> Integer.valueOf(3); // a == b 为true,是因为对应同一个IntegerCache游标的地址 System.out.println(a == b); Integer c = 129; Integer d = 129; // c == d 为false,是因为本身就是两个不同的地址 System.out.println(c == d); } }

3. 源码解读

Java源码系列-Integer源码:Java源码系列-Integer源码(2)

3.1 主要属性3.1.1 第一部分-常量参数

/** * A constant holding the minimum value an {@code int} can * have, -2^31. */ @Native public static final int MIN_VALUE = 0x80000000; /** * A constant holding the maximum value an {@code int} can * have, 2^31-1. */ @Native public static final int MAX_VALUE = 0x7fffffff; /** * The {@code Class} instance representing the primitive type * {@code int}. * * @since JDK1.1 */ @SuppressWarnings("unchecked") public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); /** * The number of bits used to represent an {@code int} value in two's * complement binary form. * * @since 1.5 */ @Native public static final int SIZE = 32; /** * The number of Bytes used to represent a {@code int} value in two's * complement binary form. * * @since 1.8 */ public static final int BYTES = SIZE / Byte.SIZE;

3.1.2 第二部分-数组

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 [] 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', } ; 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' }; 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; }

3.1.3 IntegerCache静态内部类

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"); // 如果设置了cache的高位,缓存就设置为[-128, high] if (integerCacheHighPropValue != null) { try { // 解析为int的静态值 int i = parseInt(integerCacheHighPropValue); // 取最大值 i = Math.max(i, 127); // 最大值是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空间为256 cache = new Integer[(high - low) 1]; int j = low; for(int k = 0; k < cache.length; k ) // 生成cache值的缓存空间 cache[k] = new Integer(j ); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }

IntegerCache为静态内部类,存储在方法区中的静态区,IntegerCache中的cache参数存储在静态区,包含了int可能值的Integer数组,默认范围是[-128,127],最大值可通过指定方式进行调整,在启动时 通过JVM参数Djava.lang.Integer.IntegerCache.high=xxx进行调整。当Integer的值范围在[-128,127]时则直接从缓存中获取对应的Integer对象, 不必重新实例化。这些缓存值都是静态且final的,避免重复的实例化和回收。

public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) // IntegerCache.cache空间如下: [0] = -128 [1] = -127 ... [129] = 1 [130] = 2 [256] = 127 // e.g. i = 1, 那就从IntegerCache.cache[1 128] => Integer.cache[129] = 1 return IntegerCache.cache[i (-IntegerCache.low)]; return new Integer(i); }

由上述代码可知,当值在[-128,127]之间时,取值是直接从IntegerCache的cache中取值。

3.2 核心方法max/min/sum方法

public final class Integer extends Number implements Comparable<Integer> { // 取两者之间的最大值 public static int max(int a, int b) { return Math.max(a, b); } // 取两者之间的最小值 public static int min(int a, int b) { return Math.min(a, b); } // 取两者之间的和 public static int sum(int a, int b) { return a b; } } public class IntegerDemoTest { @Test public void maxTest() { // a => 97, b => 98 => max => 98 System.out.println(Integer.max('a', 'b')); // a => 97, b => 98 => min => 97 System.out.println(Integer.min('a', 'b')); // a => 97, b => 98 => sum => 195 System.out.println(Integer.sum('a', 'b')); } }

getInteger方法

public final class Integer extends Number implements Comparable<Integer> { 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 { return Integer.decode(v); } catch (NumberFormatException e) { } } return val; } }

Integer.getInteger(String)的功能是根据指定的名称得到系统属性的整数值。第一个参数将被认为是系统属性的名称。系统属性可以通过 System.getProperty(java.lang.String)方法访问得到。属性值字符串将被解释成一个整数,并且以表示这个值的Integer对象形式返回。可能出现的数字格式的详细说明可以在 getProperty 的定义说明里找到。

@Test public void testGetInteger() { System.setProperty("test-integer", "55"); Integer testNumber = Integer.getInteger("test-integer"); Assertions.assertEquals(55, testNumber); }

toString方法

public final class Integer extends Number implements Comparable<Integer> { 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); } public String toString() { return toString(value); } public static String toString(int i, int radix) { 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]; 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)); } }

一共有3个toString方法,两个静态方法一个是非静态方法,第一个toString方法很简单,就是先用stringSize得到数字是多少位,再用getChars获取数字对应的char数组,最后返回一个String类型。第二个toString调用第一个toString。第三个toString方法是带了进制信息的,它会转换成对应进制的字符串。凡是不在2到36进制范围之间的都会被处理成10进制,我们都知道从十进制转成其他进制时就是不断地除于进制数得到余数,然后把余数反过来串起来就是最后结果,所以这里其实也是这样子做的,得到余数后通过digits数组获取到对应的字符,而且这里是用负数的形式来运算的。

reverseBytes方法

public final class Integer extends Number implements Comparable<Integer> { public static int reverseBytes(int i) { return ((i >>> 24) ) | ((i >> 8) & 0xFF00) | ((i << 8) & 0xFF0000) | ((i << 24)); } }

该方法返回通过反转指定int值的二进制补码表示形式的字节顺序而获得的值。

signum方法

public final class Integer extends Number implements Comparable<Integer> { public static int signum(int i) { // HD, Section 2-7 return (i >> 31) | (-i >>> 31); } }

改方法确定输入的数的符号,如果输入的是正数则返回1,如果输入的是零则返回0,如果输入的是负数则返回-1。

@Test public void testSignum() { // the result is -1 System.out.println(Integer.signum(-99)); // the result is 1 System.out.println(Integer.signum(99)); // the result is 0 System.out.println(Integer.signum(0)); }

reverse方法

public final class Integer extends Number implements Comparable<Integer> { 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; i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24); return i; } }

用于返回指定int值的二进制补码二进制表示形式的位的相反顺序。

@Test public void testReverse() { // the result is 100663296 System.out.println(Integer.reverse(96)); }

rotateLeft/rotateRight方法

public final class Integer extends Number implements Comparable<Integer> { public static int rotateRight(int i, int distance) { return (i >>> distance) | (i << -distance); } public static int rotateLeft(int i, int distance) { return (i << distance) | (i >>> -distance); } }

rotateRight该方法通过将指定int值a的二进制补码二进制表示形式向右旋转指定位数来返回获得的值。位向右移,即低位。

public static void main(String[] args){ int a = 64; int shifts = 0; while (shifts < 3) { // It will return the value obtained by rotating left a = Integer.rotateRight(a, 2); System.out.println(a); shifts ; } }

16 4 1

rotateLeft该方法返回通过将指定int值的二进制补码二进制表示形式向左旋转指定数量的移位位数而获得的值。

public static void main(String[] args){ int a = 2; int shifts = 0; while (shifts < 6) { // It will return the value obtained by rotating left a = Integer.rotateLeft(a, 2); System.out.println(a); shifts ; } }

8 32 128 512 2048 8192

numberOfLeadingZeros/numberOfTrailingZeros方法

public final class Integer extends Number implements Comparable<Integer> { public static int numberOfLeadingZeros(int i) { // HD, Figure 5-6 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); } }

highestOneBit/lowestOneBit方法

public final class Integer extends Number implements Comparable<Integer> { // 返回一个 int 值,最多有一个单个位,位于指定 int 值中最高(“最左边”)一位的位置。 如果指定的值在其二进制补码表示中没有一位,即等于零,则返回零。 public static int highestOneBit(int i) { // HD, Figure 3-1 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) { // 返回一个 int 值,最多只有一个一位,位于指定 int 值中最低位(“最右边”)一位的位置。 如果指定的值在其二进制补码表示中没有一位,即等于零,则返回零。 // HD, Section 2-1 return i & -i; } }

toUnsignedLong方法

public final class Integer extends Number implements Comparable<Integer> { /** * * @param x 它是一个用于转换为 unsigned long 的值。 * @return */ public static long toUnsignedLong(int x) { return ((long) x) & 0xffffffffL; } }

它通过无符号转换将参数转换为 long。在对 long 的无符号转换中,long 的 high-order 32 位为零,低 32 位等于整数参数地位。

divideUnsigned方法

public final class Integer extends Number implements Comparable<Integer> { /** * e.g. dividend=55,divisor=5, result为11 * @param dividend 它是一个将被分割的 int 值。 * @param divisor 将进行除法过程的值。 * @return */ 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)); } }

该方法它返回第一个参数除以第二个参数的无符号商,其中每个参数和结果都被解释为一个无符号值。

remainderUnsigned方法

public final class Integer extends Number implements Comparable<Integer> { /** * dividend=56, divisor=5, the result is 1 * @param dividend 它是一个将被分割的 int 值 * @param divisor 将进行除法过程的值 * @return */ 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)); } }

它返回第一个参数除以第二个参数的无符号余数,其中每个参数和结果都被解释为无符号值。

4.经典面试题1. Integer a = 1、Integer a = new Integer(1)、Integer a = Integer.valueOf(1)的区别2. 你所了解到IntegerCache5. 文章参考

1.https://www.cmsblogs.com/article/1389544331186147328

,