Integer源码分析

包装类之Integer(Long同理)

类声明:

public final class Integer extends Number implements Comparable<Integer>

和Byte差不多,就不做过多说明了

成员变量:

1.MIN_VALUE :定义Integer的最小值:2-31

 public static final int   MIN_VALUE = 0x80000000;

2.MAX_VALUE :定义了Integer的最大值:231-1

    public static final int   MAX_VALUE = 0x7fffffff;
  1. TYPE:定义了Integer对应的基本类型:int
    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

4.digits : String和Integer的转换有关系

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

说明:源码上给的注释是:All possible chars for representing a number as a String

5.DigitTens: getChars()里面会用到,就是一个工具,没有太多的作用

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

6.DigitOnes :getChars()里面会用到,就是一个工具,没有太多的作用

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

7.sizeTable:stringSize(int x)里面会用到,也是一个工具,用于得到一个整数的位数

 final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

8.value:真正存储相应的int值

  private final int value;

8.SIZE :规定Integer的大小为232

 public static final int SIZE = 32;

内置类:IntegerCache:和ByteCache一样(注意这个是真的’一模一样’)

private static class IntegerCache {
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
        cache[i] = new Integer(i - 128);
    }
    }

构造器:

有两个,可以通过String/int将value初始化

  public Integer(int value) {
    this.value = value;
    }

  public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
    }

类方法:

1.toString(int i, int radix):将形参i转换成对应的radix进制的字符串

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

说明:

  • 最常用也是最重要的几个方法之一,这是毫无疑问的。
  • 方法修饰符为public static 所以可以直接Integer.toString(int ,int)来调用。
  • 两个形参:第一个为要转成字符串的整数,第二个参数为返回的字符串以什么进制表示
  • Character.MIN_RADIX 和 Character.MAX_RADIX 分别为 2 和 32。所以进制只能是2-32之间,不在这之间的都以十进制返回
  • 如果是10进制,那么将调用重载方法toString(int),这个方法更快?为什么?
  • 注意进入到while循环中的i永远是负数。

自己实现的toString(int i, int radix):

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

    char buf[] = new char[33];
    boolean negative = (i < 0);
    int charPos = 32;
    int j = i;
    while(i!=0){
        buf[charPos--] = digits[Math.abs(i%radix)];
        i = i/radix;
    }
    if(j<0){
        buf[charPos--]='-';
    }
    charPos++;
    return new String(buf, charPos, (33 - charPos));
    }

2.toHexString(int i)/toOctalString(int i)/toBinaryString(int i):以十六进制/八进制/二进制的无符号整数形式返回一个整数参数的字符串表示形式。

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

可以看出底层调用的是toUnsignedString(i, 4/3/1),后面会分析这个

3.toUnsignedString(int i, int shift):将无符号的整数转成字符串

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

说明:上面内三个函数的’御用’方法(这个方法没在其他地方出现过)
原理:一个数和3进行与运算,就是对4取余.同理1个数和5进行与运算就是对6取余,和7进行与运算就是对8取余,依次类推。 关于与运算和取余之间的关系

4.toString(int i):将整数按十进制的方式转换成字符串,就好像将参数和基数 10 作为参数赋予 toString(int, int) 方法。但是实现方法完全不一样

  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(0, size, buf);
    }

说明:
stringSize(int): 返回int的最高位数(比如1000就返回4,10就返回2),但是只能参数只接受正数
getChars(i, size, buf):将i放入字符数组buf中,最后在转成字符串。

5.getChars(int i, int index, char[] buf):将整数按字符串的形式放入字符数组中:有优化java性能的思想在里面知乎–java源码中Integer.class中有个getChars方法,里面有个52429是怎么确定的?

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);
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        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;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }

6.stringSize(int x):得到一个正整数的位数

    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }

7. parseInt(String s, int radix):将字符串转成整数,第二个参数为进制

public static int parseInt(String s, int radix)
        throws NumberFormatException
    {
        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, max = s.length();
    int limit;
    int multmin;
    int digit;

    if (max > 0) {
        if (s.charAt(0) == '-') {
        negative = true;
        limit = Integer.MIN_VALUE;
        i++;
        } else {
        limit = -Integer.MAX_VALUE;
        }
        multmin = limit / radix;

        if (i < max) {
        //digit:返回字符的int值
        digit = Character.digit(s.charAt(i++),radix);
        if (digit < 0) {
            throw NumberFormatException.forInputString(s);
        } else {
            result = -digit;
        }
        }
        while (i < max) {
        // 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);
    }//第一个if-else结束
    if (negative) {
        if (i > 1) {
        return result;
        } else {    /* Only got "-" */
        throw NumberFormatException.forInputString(s);
        }
    } else {
        return -result;
    }
    }

说明:

  • 前面的判断异常跳过去,这没什么好说的
  • 首先看懂代码的结构:两个if-else,按照代码量一大一小,
  • 第一个是大的,里面两个if还有一个while,第一个if为判断字符串是否有负号,给提出来;第二个if意思是取下一个字符并将其转换为int,然后用这个整数去初始化;然后while循环读取剩下的字符,并重复第二个if的过程。这样最后得到的是整个结果的取反值
  • 第二个是小的,判断原来的字符串有没有负号,返回相应的整数

8. parseInt(String s):将字符串转成整数(10进制VIP版),

 public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s,10);
    }

9.两个没有卵用的valueOf(),和parseInt()重复了,本质是调用parseInt()

    public static Integer valueOf(String s, int radix) throws NumberFormatException {
    return new Integer(parseInt(s,radix));
    }

    public static Integer valueOf(String s) throws NumberFormatException
    {
    return new Integer(parseInt(s, 10));
    }

10.valueOf(int i):还有一个valueOf(int i) 和Byte里面的’一模一样’

  public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }

11.三个getInteger() :返回系统属性的一个对应的Integer(好多属性都是null)

 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) ? new Integer(val) : result;
    }

    public static Integer getInteger(String nm, Integer val) {
    String v = null;
        try {
            v = System.getProperty(nm);     //调用System.getProperty(nm)方法
        } catch (IllegalArgumentException e) {
        } catch (NullPointerException e) {
        }
    if (v != null) {
        try {
        return Integer.decode(v);
        } catch (NumberFormatException e) {
        }
    }
    return val;             //可是返回值与v无关
    }

12.decode(String nm):将 String 解码为 Integer。接受通过以下语法给出的十进制、十六进制和八进制数字。(0x,0,#这些)

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

        // Handle minus sign, if present
        if (nm.startsWith("-")) {
            negative = true;
            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))
            throw new NumberFormatException("Negative sign in wrong position");

        try {
            result = Integer.valueOf(nm.substring(index), radix);
            result = negative ? new Integer(-result.intValue()) : 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 ? new String("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }
        return result;
    }

13.highestOneBit(int i):返回具有至多单个 1 位的 int 值,在指定的 int 值中最高位(最左边)的 1 位的位置。如果指定的值在其二进制补码表示形式中不具有 1 位,即它等于零,则返回零

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

14.lowestOneBit(int i): 返回具有至多单个 1 位的 int 值,在指定的 int 值中最低位(最右边)的 1 位的位置。如果指定的值在其二进制补码表示形式中不具有 1 位,即它等于零,则返回零。

public static int lowestOneBit(int i) {
        // HD, Section 2-1
        return i & -i;
    }

15.numberOfLeadingZeros(int i):返回指定的 int 值的二进制补码表示形式中最低(“最右”)的为 1 的位后面的零位个数。如果指定值在它的二进制补码表示形式中没有为 1 的位,即它的值为零,则返回 32。

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

16.其余各种与位运算符有关的就不分析了,源码贴在这里了

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

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


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

    public static int signum(int i) {
        // HD, Section 2-7
        return (i >> 31) | (-i >>> 31);
    }

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

对象方法:

1.各种类型转换:

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


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

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

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

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

2.toString():将value转成字符串,注意调用的valueOf()并不是Integer的,而是String的

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

3.hashCode():基本类型的hashCode就是他自己

    public int hashCode() {
        return value;
    }
  1. equals(Object obj):注意为了重写Object的equals()方法,参数类型是Object,但是通过instanceof传入的类型实质还是Integer
 public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
    }

5.compareTo():比较两个Integer的value的大小(小于返回-1,等于为0,大于为1)

 public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值