Integer源码解析

一、前言

    Integer类是我们经常用到的一个基础类,学习其底层结构有助于我们在项目中更加得心应手的使用他,并且能够有效避免Integer所遇到的坑。这篇博客主要是介绍Integer经常使用的几个方法其源码是怎么做的,而且针对Integer的一些变量进行解释,这会有助于我们读懂Integer的源码。

二、源码解析

继承了哪些类

在这里插入图片描述
    由上图可知Integer继承了Number抽象类和实现了Comparable接口。

变量说明

// 0x80000000 转换为十进制值为 -2^31,它表示 int 类型能够表示的最小值
@Native
public static final int MIN_VALUE = 0x80000000;

// 0x7fffffff 转换为十进制值为 2^31-1,它表示 int 类型能够表示的最大值
@Native
public static final int MAX_VALUE = 0x7fffffff;

// 表示基本类型 int 的 Class 实例
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

// 用于将数字表示为字符串的所有可能字符
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'
};

// 用在判断一个int类型数字对应字符串的长度,非常巧妙。
final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
        99999999, 999999999, Integer.MAX_VALUE};

// 保存Integer类中的真实基本数据类型的值
private final int value;

构造方法

    Integer类的构造方法只有两个,如下所示:

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

/**
 * 以字符串为参数的构造方法
 * 默认返回十进制的值
 *
 * @param s
 * @throws NumberFormatException
 */
public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
}

常用方法

String toString(int i, int radix)方法:转化对应进制的数字为十进制。

/**
 * 转化对应进制的数字为十进制
 *
 * @param i     目标数字
 * @param radix 对应的进制数
 * @return
 */
public static String toString(int i, int radix) {
    // 如果进制数小于2进制或者大于36进制,则改用十进制。
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        radix = 10;

    // 如果是十进制,用最快的版本
    if (radix == 10) {
        return toString(i);
    }
    // 创建一个33位的字符数组,当负数时:1位符号位+32位数字;正数时,32位数字。
    char buf[] = new char[33];
    boolean negative = (i < 0);
    int charPos = 32;
    // 将正数转为负数进行运算,防止负数转为正数的溢出情况,即i一直为负数
    if (!negative) {
        i = -i;
    }
    // 此循环则是根据i和radix获取求余的值并且以倒序放到buf数组中
    while (i <= -radix) {
        buf[charPos--] = digits[-(i % radix)];
        i = i / radix;
    }
    buf[charPos] = digits[-i];
    // 若是负数,加减号
    if (negative) {
        buf[--charPos] = '-';
    }
    // 返回一个字符串,参数为char数组,起始位置,字符长度
    return new String(buf, charPos, (33 - charPos));
}

toString(int i)方法:返回当前数字(十进制)的字符串形式。

/**
 * 返回当前数字(十进制)的字符串形式
 *
 * @param i
 * @return
 */
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];
    // 将数字分成一个个char,保存到buf数组中
    getChars(i, size, buf);
    // 通过数组buf返回一个字符串,后面的参数share=true应该是没有用的
    return new String(buf, true);
}

/**
 * 判断一个int类型数字的长度
 *
 * @param x
 * @return
 */
static int stringSize(int x) {
    for (int i = 0; ; i++)
        if (x <= sizeTable[i])
            return i + 1;
 }

parseInt(String s)方法:返回指定字符串的一个Integer对象(10进制)。

/**
 * 返回指定字符串的一个Integer对象(10进制)
 *
 * @param s
 * @return
 * @throws NumberFormatException
 */
public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s, 10);
}

/**
 * 返回输入字符串的指定进制的正整数
 *
 * @param s     字符串
 * @param radix 指定的进制数
 * @return
 * @throws NumberFormatException
 */
public static int parseInt(String s, int radix) throws NumberFormatException {
    /**
     * 警告:此方法可能在VM初始化期间,初始化IntegerCache之前提早调用。必须注意不要使用valueOf方法。
     */
    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, len = s.length();
    int limit = -Integer.MAX_VALUE;
    int multmin;
    int digit;
    
    //判断字符串是否不为空,即是否有传入字符串
    if (len > 0) {
        //获取字符串的第一个字符,有可能是数字,或者+/-,也有可能是其他符号比如 * 等
        char firstChar = s.charAt(0);
        // 如果第一个字符小于0,即有可能为"+" or "-"
        if (firstChar < '0') {
            //若为第一个字符为"-",则表示字符串要转换的是一个负数
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+') //若不等于“+”,则有可能字符串的第一个字符为其他符号,则此字符串不是一个数值
                throw NumberFormatException.forInputString(s);
            // len为1的情况则为只有"+"或者"-"符号,也表明字符串不是一个数值
            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++;
        }
        multmin = limit / radix;
        // 将字符串的数字转为对应进制的数字
        while (i < len) {
            // 将字符串的数字部分的一个数字(对应进制),通过Character类转为进制的数
            digit = Character.digit(s.charAt(i++), radix);
            // 若字符串中的某一个字符,在字符串进制下(radix)是无效的,则返回-1
            // 此时则抛出异常即可
            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;
}

valueOf(String s)方法:将字符串转换为十进制的Integer。

/**
 * 将字符串转换为十进制的Integer
 *
 * @param s
 * @return
 * @throws NumberFormatException
 */
public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

/**
 * 返回一个表示指定的 int 值的 Integer 实例。
 * 如果不需要新的 Integer 实例,则通常应优先使用该方法
 * 而不是构造方法 Integer(int),因为该方法可以通过缓存经常请求的值而显著提高空间和时间性能。
 *
 * @param i
 * @return
 */
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        // 直接获得在[low,high]范围内的IntegerCache缓存的Integer对象,不在该范围则重新实例化Integer对象
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

hashCode()方法:返回此 Integer 的哈希码。

/**
 * 返回此 Integer 的哈希码
 *
 * @return
 */
@Override
public int hashCode() {
    return Integer.hashCode(value);
}

/**
 * 返回{@code int}值的哈希码;与{@code Integer.hashCode()}兼容。
 *
 * @param value
 * @return
 */
 public static int hashCode(int value) {
    return value;
}

equals(Object obj)方法:比较此对象与指定对象是否相等。

/**
 * 比较此对象与指定对象。当且仅当参数不为 null,
 * 并且是一个与该对象包含相同 int 值的 Integer 对象时,结果为 true。
 *
 * @param obj
 * @return
 */
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer) obj).intValue();
    }
    return false;
}

getInteger(String nm)方法:返回系统常量的int值,类似System.getProperty(str)

/**
 * 返回系统常量的int值,类似System.getProperty(str);
 *
 * @param nm 属性名,系统常量
 * @return
 */
public static Integer getInteger(String nm) {
    return getInteger(nm, null);
}

/**
 * 返回系统常量的int值,类似System.getProperty(str);
 * 如果获取的系统常量值为空,则返回val
 *
 * @param nm  属性名,系统常量
 * @param val 默认值
 * @return
 */
public static Integer getInteger(String nm, int val) {
    Integer result = getInteger(nm, null);
    return (result == null) ? Integer.valueOf(val) : result;
}

/**
 * 返回具有指定名称的系统属性的整数值
 *
 * @param nm  属性名,系统常量
 * @param val 默认值
 * @return
 */
 public static Integer getInteger(String nm, Integer val) {
    String v = null;
    try {
        //获取系统常量对应的值
        v = System.getProperty(nm);
    } catch (IllegalArgumentException | NullPointerException e) {
    }
    if (v != null) {
        try {
            // 如果获取的不为空值,则通过解码函数返回对饮的int值,否则则返回默认值val
            return Integer.decode(v);
        } catch (NumberFormatException e) {
        }
    }
    return val;
}

compareTo(Integer anotherInteger)方法:比较两个Integer对象的value值大小。

/**
 * 比较两个 Integer 对象的value值大小
 *
 * @param anotherInteger
 * @return
 */
public int compareTo(Integer anotherInteger) {
    return compare(this.value, anotherInteger.value);
}

/**
 * 比较两个int类型的值的大小,很巧妙,值得学习
 *
 * @param x
 * @param y
 * @return
 */
public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

三、总结

    Integer类里面很多巧妙的代码非常值得我们去学习,能够读懂这些的话将会对自己的能力有所提升。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值