jdk源码之Integer

130 阅读7分钟

面试题

请写出下面代码段的输出值:

public static void main(String[] args) {
   Integer a = 888;
   Integer b = 888;
   Integer c = 88;
   Integer d = 88;
   System.out.println(a == b);
   System.out.println(c == d);
}
public static void main(String[] args) {
   Integer a = new Integer(88);
   test(a);
   System.out.println(a);
}
private void test(Integer integer){
   integer=new Integer(99);
}

想要彻底了解原理,请跟着学习下面的源码内容!

##成员变量

image.png

##构造方法

image.png

其他方法

static intbitCount​(int i)返回指定的 int值的二进制补码表示形式中的 int 。
bytebyteValue()返回此值 Integer为 byte的基本收缩转换后。
static intcompare​(int x, int y)以数字方式比较两个 int值。
intcompareTo​(Integer anotherInteger)以数字方式比较两个 Integer对象。
static intcompareUnsigned​(int x, int y)比较两个 int值,将数值视为无符号。
static Integerdecode​(String nm)将 String解码为 Integer 。
static intdivideUnsigned​(int dividend, int divisor)返回将第一个参数除以第二个参数的无符号商,其中每个参数和结果都被解释为无符号值。
doubledoubleValue()返回此值 Integer为 double一个宽元转换后。
booleanequals​(Object obj)将此对象与指定的对象进行比较。
floatfloatValue()返回此值 Integer为 float一个宽元转换后。
static IntegergetInteger​(String nm)确定具有指定名称的系统属性的整数值。
static IntegergetInteger​(String nm, int val)确定具有指定名称的系统属性的整数值。
static IntegergetInteger​(String nm, Integer val)返回具有指定名称的系统属性的整数值。
inthashCode()返回此 Integer的哈希码。
static inthashCode​(int value)返回int值的哈希码; 与Integer.hashCode()兼容。
static inthighestOneBit​(int i)返回 int值,最多只有一位,位于指定 int值中最高位(“最左侧”)一位的位置。
intintValue()返回此值 Integer为 int 。
longlongValue()在扩展基元转换后,将此 Integer的值作为 long返回。
static intlowestOneBit​(int i)返回 int值,最多只有一位,位于指定 int值中最低位(“最右侧”)一位的位置。
static intmax​(int a, int b)返回两个 int值中较大的一个, int调用 Math.max一样 。
static intmin​(int a, int b)返回两个 int值中较小的一个, int调用 Math.min一样 。
static intnumberOfLeadingZeros​(int i)返回指定 int值的二进制补码二进制表示中最高位(“最左侧”)一位之前的零位数。
static intnumberOfTrailingZeros​(int i)返回指定 int值的二进制补码表达式中最低位(“最右侧”)一位后的零位数。
static intparseInt​(CharSequence s, int beginIndex, int endIndex, int radix)解析CharSequence参数作为有符号int指定radix ,在指定的开始beginIndex并延伸到endIndex - 1 。
static intparseInt​(String s)将字符串参数解析为带符号的十进制整数。
static intparseInt​(String s, int radix)将字符串参数解析为第二个参数指定的基数中的有符号整数。
static intparseUnsignedInt​(CharSequence s, int beginIndex, int endIndex, int radix)解析CharSequence参数为一个无符号int在指定的radix ,在指定的开始beginIndex并延伸到endIndex - 1 。
static intparseUnsignedInt​(String s)将字符串参数解析为无符号十进制整数。
static intparseUnsignedInt​(String s, int radix)将字符串参数解析为第二个参数指定的基数中的无符号整数。
static intremainderUnsigned​(int dividend, int divisor)返回将第一个参数除以第二个参数的无符号余数,其中每个参数和结果都被解释为无符号值。
static intreverse​(int i)返回通过反转指定的 int值的二进制补码二进制表示中的位顺序获得的值。
static intreverseBytes​(int i)返回通过反转指定的 int值的二进制补码表示中的字节顺序获得的值。
static introtateLeft​(int i, int distance)返回通过旋转指定 int留下的指定 int值的二进制补码表达式获得的值。
static introtateRight​(int i, int distance)返回通过将指定的 int值的二进制补码表达式旋转指定的 int值。
shortshortValue()返回此值 Integer为 short的基本收缩转换后。
static intsignum​(int i)返回指定的 int值的signum函数。
static intsum​(int a, int b)根据+运算符将两个整数相加。
static StringtoBinaryString​(int i)返回整数参数的字符串表示形式,作为base 2中的无符号整数。
static StringtoHexString​(int i)返回整数参数的字符串表示形式,作为基数为16的无符号整数。
static StringtoOctalString​(int i)返回整数参数的字符串表示形式,作为基数为8的无符号整数。
StringtoString()返回表示此 Integer值的 String对象。
static StringtoString​(int i)返回表示指定整数的 String对象。
static StringtoString​(int i, int radix)返回第二个参数指定的基数中第一个参数的字符串表示形式。
static longtoUnsignedLong​(int x)通过无符号转换将参数转换为 long 。
static StringtoUnsignedString​(int i)以无符号十进制值的形式返回参数的字符串表示形式。
static StringtoUnsignedString​(int i, int radix)返回第一个参数的字符串表示形式,作为第二个参数指定的基数中的无符号整数值。
static IntegervalueOf​(int i)返回表示指定的 int值的 Integer实例。
static IntegervalueOf​(String s)返回一个 Integer物体保持在指定的值 String 。
static IntegervalueOf​(String s, int radix)返回 Integer对象,当使用第二个参数给出的基数进行解析时,该对象保存从指定的 String提取的值。

重要方法分析

构造方法

构造方法从Java9开始标记为废弃方法。调用构造方法都会生成新的对象。

@Deprecated(since="9", forRemoval = true)
public Integer(int value) {
    this.value = value;
}

@Deprecated(since="9", forRemoval = true)
public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
}

parseInt方法

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.
     */
    // 如果输入的值为空,则直接抛出NumberFormatException
    if (s == null) {
        throw new NumberFormatException("Cannot parse null string");
    }
    // 若是进制小于2则抛出异常
    if (radix < Character.MIN_RADIX) {
        throw new NumberFormatException("radix " + radix +
                " less than Character.MIN_RADIX");
    }
    // 若进制大于36则抛出异常
    if (radix > Character.MAX_RADIX) {
        throw new NumberFormatException("radix " + radix +
                " greater than Character.MAX_RADIX");
    }
    // 默认是正数
    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, radix);
            }
            // 若是待转换数仅有一个正负号,也会抛出异常
            if (len == 1) { // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s, radix);
            }
            i++;
        }
        //算出该进制下的最小值
        int multmin = limit / radix;
        int result = 0;
        // 待转换数的每一位处理,若是不带符号,则i=0开始,若是带符号i=1开始
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            // 获取该字符对应进制中的十进制数值
            int digit = Character.digit(s.charAt(i++), radix);
            if (digit < 0 || result < multmin) {
                throw NumberFormatException.forInputString(s, radix);
            }
            //多一位则多乘一次进制
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s, radix);
            }
            //用复数来计算所以先减
            result -= digit;
        }
        // 是负数则直接返回result,正数则取反
        return negative ? result : -result;
    } else {
        throw NumberFormatException.forInputString(s, radix);
    }
}
public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s,10);
}
/**
 * @since  9
 */
public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix)
            throws NumberFormatException {
    Objects.requireNonNull(s);
    Objects.checkFromToIndex(beginIndex, endIndex, s.length());

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

    boolean negative = false;
    int i = beginIndex;
    int limit = -Integer.MAX_VALUE;

    if (i < endIndex) {
        char firstChar = s.charAt(i);
        if (firstChar < '0') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+') {
                throw NumberFormatException.forCharSequence(s, beginIndex,
                        endIndex, i);
            }
            i++;
            if (i == endIndex) { // Cannot have lone "+" or "-"
                throw NumberFormatException.forCharSequence(s, beginIndex,
                        endIndex, i);
            }
        }
        int multmin = limit / radix;
        int result = 0;
        while (i < endIndex) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            int digit = Character.digit(s.charAt(i), radix);
            if (digit < 0 || result < multmin) {
                throw NumberFormatException.forCharSequence(s, beginIndex,
                        endIndex, i);
            }
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forCharSequence(s, beginIndex,
                        endIndex, i);
            }
            i++;
            result -= digit;
        }
        return negative ? result : -result;
    } else {
        throw NumberFormatException.forInputString("", radix);
    }
}

valueOf方法

使用valueOf时,入参在-128到127之间都会从缓存中取值返回,故而对象是同一个。

@IntrinsicCandidate
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, int radix) throws NumberFormatException {
    return Integer.valueOf(parseInt(s,radix));
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer[] cache;
    static Integer[] archivedCache;

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                h = Math.max(parseInt(integerCacheHighPropValue), 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        // Load IntegerCache.archivedCache from archive, if possible
        CDS.initializeFromArchive(IntegerCache.class);
        int size = (high - low) + 1;

        // Use the archived cache if it exists and is large enough
        if (archivedCache == null || size > archivedCache.length) {
            Integer[] c = new Integer[size];
            int j = low;
            for(int i = 0; i < c.length; i++) {
                c[i] = new Integer(j++);
            }
            archivedCache = c;
        }
        cache = archivedCache;
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

hashCode方法

Integer的hashCode值是它的value。

@Override
public int hashCode() {
    return Integer.hashCode(value);
}

/**
 * @since 1.8
 *
 * @return a hash code value for an {@code int} value.
 */
public static int hashCode(int value) {
    return value;
}

decode方法

此方法是将String表示的数转为十进制数输出,传参可以为十进制八进制16进制, 可选符号和/或基数说明符(“0x”、“”、“0X”#或前导零)后面的字符序列由具有指示基数(10、16 或 8)的方法解析 Integer.parseInt 。此字符序列必须表示正值,否则将抛出 a NumberFormatException 。如果指定 String 的第一个字符是减号,则结果为否定。中 String不允许使用空格字符。

public static Integer decode(String nm) throws NumberFormatException {
    int radix = 10;
    int index = 0;
    boolean negative = false;
    int result;

    if (nm.isEmpty())
        throw new NumberFormatException("Zero length string");
    char firstChar = nm.charAt(0);
    // Handle sign, if present
    if (firstChar == '-') {
        negative = true;
        index++;
    } else if (firstChar == '+')
        index++;

    // Handle radix specifier, if present
    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 = parseInt(nm, index, nm.length(), radix);
        result = negative ? -result : result;
    } catch (NumberFormatException e) {
        // If number is Integer.MIN_VALUE, we'll end up here. The next line
        // handles this case, and causes any genuine format error to be
        // rethrown.
        String constant = negative ? ("-" + nm.substring(index))
                                   : nm.substring(index);
        result = parseInt(constant, radix);
    }
    return result;
}

bitCount

返回指定 int 值的二进制补码二进制表示形式中的1位数。

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