Long源码分析。

public final class Long extends Number implements Comparable<Long> {
    /*
     * 继承Number类提供将表示的数值转换为 byte、double、float、int、long 和 short 的方法。<br />
     * 实现Comparable接口,获取到compareTo方法。
     */
    // 保持 long 类型的最小值的常量,该值为 -2的63方
    public static final long MIN_VALUE = 0x8000000000000000L;
    // 保持 long 类型的最大值的常量,该值为 2的63方-1
    public static final long MAX_VALUE = 0x7fffffffffffffffL;
    // 表示基本类型 long 的 Class 实例
    public static final Class<Long>     TYPE = (Class<Long>) Class.getPrimitiveClass("long");
	/**
	 * 转化对应进制的数字为十进制
	 * @param i	要转换为字符串的 long
	 * @param radix	进制数
	 * @return String 
	 */
    public static String toString(long i, int radix) {
        // 如果进制数小于2进制 或者大于 26进制,则改用十进制。 
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;
        /* 如果是十进制,用最快的版本 */
        if (radix == 10)
            return toString(i);
        // 创建一个65位的字符数组(负数时:1位符号位+64位数字;正数时,64位数字)
        char[] buf = new char[65];
        int charPos = 64;
        boolean negative = (i < 0);
        // 将正数转为负数进行运算,防止负数转为正数的溢出情况
        if (!negative) {
            i = -i;
        }
        // 循环判断当前转换的字符是否小于计数的相反数
        while (i <= -radix) {
            //根据余数的相反数在digits数组中获取相应的字符,倒序存放到buf[]数组里
            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
            i = i / radix;
        }   
        buf[charPos] = Integer.digits[(int)(-i)];
        // 若是负数,加减号
        if (negative) {
            buf[--charPos] = '-';
        }
        // 返回一个字符串,参数为char数组、起始位置、字符长度
        return new String(buf, charPos, (65 - charPos));
    }
	/**
	 * 返回当前long的16进制的字符串形式
	 * @param i	要转换为字符串的 long
	 * @return String 
	 */
    public static String toHexString(long i) {
        return toUnsignedString(i, 4);
    }
    /**
     * 返回当前long的8进制的字符串形式
     * @param i	要转换为字符串的 long
     * @return String 
     */
    public static String toOctalString(long i) {
        return toUnsignedString(i, 3);
    }
    /**
     * 返回当前long的2进制的字符串形式
     * @param i	要转换为字符串的 long
     * @return String 
     */
    public static String toBinaryString(long i) {
        return toUnsignedString(i, 1);
    }
    /**
     * 返回当前long类型的i的shift进制的字符串形式的私有工具类
     * @param i
     * @param shift	进制数
     * @return String 
     */
    private static String toUnsignedString(long i, int shift) {
        char[] buf = new char[64];
        int charPos = 64;
        // 算数左移,radix中间变量用于计算mask
        int radix = 1 << shift;
        // mask掩码用于获取i的shift位低位,mask二进制数每一位都是1
        long mask = radix - 1;
        do {
            //取出i二进制数低位shift位,将对应的字符存入buf
            buf[--charPos] = Integer.digits[(int)(i & mask)];
            //逻辑右移,剔除已取出的shfit位低位
            i >>>= shift;
        } while (i != 0);
        return new String(buf, charPos, (64 - charPos));
    }
    /**
     * 返回当前long的字符串形式
     * @param i
     * @return String 
     */
    public static String toString(long i) {
        if (i == Long.MIN_VALUE)
            return "-9223372036854775808";
        // 判断是否为负数,计算长度
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        // 将数字分成一个个char,保存到buf数组中
        getChars(i, size, buf);
        return new String(buf, true);
    }
    /**
     * 将某个long型数值写入到字符数组中(若i等于Long.MIN_VALUE,则为失败)
     * 几种运算的耗时长短:除法运算>乘法运算>移位结合加法的运算
     * @param i	long型数值
     * @param index	长度
     * @param buf buf数组
     * @return void 
     */
    static void getChars(long i, int index, char[] buf) {
        long q;
        int r;
        int charPos = index;
        char sign = 0;
        // 负数的处理
        if (i < 0) {
            sign = '-';
            i = -i;
        }
        // i大于int最大值
        while (i > Integer.MAX_VALUE) {
            q = i / 100;
            // really: r = i - (q * 100);
            r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
            // 将商赋给i,继续循环,直到小于2147483647 
            i = q;
            // 取DigitOnes[r]的值其实取数字r%10的结果
            buf[--charPos] = Integer.DigitOnes[r];
            // 取DigitTens[r]的值其实取数字r/10的结果
            buf[--charPos] = Integer.DigitTens[r];
        }
        // i大于等于65536,16次方
        int q2;
        int i2 = (int)i;
        while (i2 >= 65536) {
            q2 = i2 / 100;
            // really: r = i2 - (q * 100);
            r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
            // 将商赋给i,继续循环,直到小于65536
            i2 = q2;
            // 取DigitOnes[r]的值其实取数字r%10的结果
            buf[--charPos] = Integer.DigitOnes[r];
            // 取DigitTens[r]的值其实取数字r/10的结果
            buf[--charPos] = Integer.DigitTens[r];
        }
        // 对于较小的数字,进入快速模式
        // 循环存放低两字节的数字存放到字符数组中空余位置
        for (;;) {
            // 右移19位
            /**
             * >>>: 无符号的右移
             * >>: 有符号的右移
             */
            q2 = (i2 * 52429) >>> (16+3);
            r = i2 - ((q2 << 3) + (q2 << 1));  // r = i2-(q2*10) ...
            // 从digit数组中取数
            buf[--charPos] = Integer.digits[r];
            i2 = q2;
            //整数写入字符数组完成
            if (i2 == 0) break;
        }
            //整数写入字符数组完成
        if (sign != 0) {
            buf[--charPos] = sign;
        }
    }
    /**
     * 判断一个long类型数字的长度
     * @param x	long类型的整数
     * @return int 
     */
    static int stringSize(long x) {
        long p = 10;
        for (int i=1; i<19; i++) {
            if (x < p)
                return i;
            p = 10*p;
        }
        return 19;
    }
    /**
     * 返回输入字符串的指定进制的long值
     * @param s	
     * @param radix	进制数
     * @throws NumberFormatException 
     * @return long 
     */
    public static long parseLong(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");
        }
      // 保存结果 
        long result = 0;
      // 判断正负
        boolean negative = false;
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;
        long multmin;
        int digit;

        if (len > 0) {// 字符串的长度大于零
            // 取第一个值
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // 如果第一个字符小于0 
                if (firstChar == '-') {// 为负数
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if (firstChar != '+')//不为正数
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // 不能只有一个符号
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            // 限制的最小值(在对应进制的)
            multmin = limit / radix;
            // 将字符串的数字部分转为进制的数字(从左到右)
            while (i < len) {
                // 将字符串的数字部分的一个数字(对应进制),通过Character类转为进制的数
                // 若字符串中的某一个字符,在字符串进制下(radix)是无效的,则返回-1
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {// 若返回-1(无效)
                    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;
    }
    /**
     * 返回指定字符串的long类型的数值,默认是10进制的
     * @param s	long类型的数值
     * @throws NumberFormatException 
     * @return long 
     */
    public static long parseLong(String s) throws NumberFormatException {
        return parseLong(s, 10);
    }
    /**
     * 返回指定转换进制的字符串的一个Long对象
     * @param s	需要转换的字符串
     * @param radix	进制数
     * @throws NumberFormatException 
     * @return Long 
     */
    public static Long valueOf(String s, int radix) throws NumberFormatException {
        return Long.valueOf(parseLong(s, radix));
    }
    /**
     * 返回指定字符串的一个Long对象,默认是10进制的
     * @param s	需要转换的字符串
     * @throws NumberFormatException 
     * @return Long 
     */
    public static Long valueOf(String s) throws NumberFormatException
    {
        return Long.valueOf(parseLong(s, 10));
    }
    /**
     * 缓存以支持自动装箱的对象标识语义.用于在-128和127
     * 缓存在第一次使用时被初始化。
     */
    private static class LongCache {
        private LongCache(){}

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

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }
    /**
     * 返回表示指定 long 值的 Long 实例。
     * 如果不需要新的 Long 实例,则通常优先使用此方法,
     * 而不是使用构造方法 Long(long),
     * 因为此方法通过缓存频繁请求的值,
     * 可以显著提高时间和空间性能。 
     * @param l
     * @return Long 
     */
    public static Long valueOf(long l) {
        final int offset = 128;
        // 直接获得在[-128,127]范围内的LongCache缓存的对象,不在该范围则重新实例化Integer对象
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
    /**
     *  将 String 解码成 Long
     * @param nm	字符串
     * @throws NumberFormatException 
     * @return Long 
     */
    public static Long decode(String nm) throws NumberFormatException {
    	// 10进制
        int radix = 10;
        int index = 0;
        // 正负数标识
        boolean negative = false;
        Long result;

        if (nm.length() == 0)
            throw new NumberFormatException("Zero length string");
        // 获取第一个字符
        char firstChar = nm.charAt(0);
        if (firstChar == '-') {// 为负数
            negative = true;
            index++;
        } else if (firstChar == '+')// 为正数
            index++;
        // 然后剩下的字符串以0x或0X开头,表示十六进制
        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        else if (nm.startsWith("#", index)) {// 或以#开头,表示十六进制
            index ++;
            radix = 16;
        }
        //若以0开头,且字符串长度大于当前判断字符数+1,则为8进制
        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 = Long.valueOf(nm.substring(index), radix);
            // 若是负数,取反包装类Long中的value的值,再进行获取该基本数据类型的包装对象实例
            result = negative ? Long.valueOf(-result.longValue()) : result;
        } catch (NumberFormatException e) {
            // 使用long类型参数转化出现异常,转而使用String类型参数进行转化
            String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
            // 转化字符串成对应的包装类的实例对象
            result = Long.valueOf(constant, radix);
        }
        return result;
    }
    // 保存Long类中的真实基本数据类型的值
    private final long value;
    /**
     * 构造一个新分配的 Long 对象,它表示指定的 long 值。
     * @param value 
     */
    public Long(long value) {
        this.value = value;
    }
    /**
     * 构造新分配的 Long 对象,表示由 String 参数指示的 long 值。
     * 该字符串被转换为 long 值,
     * 其方式与 radix 参数为 10 的 parseLong 方法所使用的方式一致。 
     * @param s	要转换为 Long 的 String
     * @throws NumberFormatException 
     * @return void 
     */
    public Long(String s) throws NumberFormatException {
        this.value = parseLong(s, 10);
    }
    /**
     * 以 byte 类型返回该 Long 的值。
     */
    public byte byteValue() {
        return (byte)value;
    }
    /**
     * 以 short 类型返回该 Integer 的值。 
     */
    public short shortValue() {
        return (short)value;
    }
    /**
     * 以 int 类型返回该 Integer 的值。
     */
    public int intValue() {
        return (int)value;
    }
	/**
	 * 以 long 类型返回该 Integer 的值。 
	 */
    public long longValue() {
        return (long)value;
    }
	/**
	 * 以 float 类型返回该 Integer 的值。 
	 */
    public float floatValue() {
        return (float)value;
    }
	/**
	 * 以 double 类型返回该 Integer 的值。 
	 */
    public double doubleValue() {
        return (double)value;
    }
	/**
	 * 返回表示 Long 值的 String 对象。
	 * 该值被转换为有符号十进制表示形式,并作为字符串返回,
	 * 该字符串与用 long 值作为参数的 toString(long) 方法
	 * 得到的字符串非常相似。 
	 */
    public String toString() {
        return toString(value);
    }
    /**
     * 返回 Long 的哈希码。
     * 结果是此 Long 对象保持的基本 long 值的两个部分的异或 (XOR)。
     */
    public int hashCode() {
        return (int)(value ^ (value >>> 32));
    }
    /**
     * 比较此对象与指定对象。当且仅当参数不为 null,
     * 并且是一个与该对象包含相同long 值的 Integer 对象时,
     * 结果为 true。 
     */
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }
    /**
     * 返回系统常量的long值,类似System.getProperty(str);
     * @param nm	属性名
     * @return Long 
     */
    public static Long getLong(String nm) {
        return getLong(nm, null);
    }
    /**
     * 返回系统常量的long值,类似System.getProperty(str);
     * 如果为空,默认值为val
     * @param nm	属性名
     * @param val	默认值
     * @return Long 
     */
    public static Long getLong(String nm, long val) {
        Long result = Long.getLong(nm, null);
        return (result == null) ? Long.valueOf(val) : result;
    }
    /**
     * 返回具有指定名称的系统属性的long值。
     * @param nm	属性名
     * @param val	默认值
     * @return Long 
     */
    public static Long getLong(String nm, Long val) {
        String v = null;
        try {// 获取对应系统变量名的值
            v = System.getProperty(nm);
        } catch (IllegalArgumentException e) {
        } catch (NullPointerException e) {
        }
        if (v != null) {
            try {//返回字符串中的数字
                return Long.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        return val;
    }
    /**
     *比较两个 Long 对象的value值大小
     */
    public int compareTo(Long anotherLong) {
        return compare(this.value, anotherLong.value);
    }
	/**
	 * 比较两个long类型的值的大小
	 * @param x
	 * @param y
	 * @return int 
	 */
    public static int compare(long x, long y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
    // 用来以二进制补码形式表示 long 值的位数
    public static final int SIZE = 64;
    /**
     * 返回在二进制情况下,i的最高位为1,其他全为0的值。
     * 将64位都置为1,然后将该值减去该值右移一位的值
     * @param i
     * @return long 
     */
    public static long highestOneBit(long i) {
        //右移一位或上原值
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        i |= (i >> 32);
        //i值减去i右移一位的值
        return i - (i >>> 1);
    }
	/**
	 * 获取最低位为1,其他位都为0的值
	 * @param i
	 * @return long 
	 */
    public static long lowestOneBit(long i) {
        // HD, Section 2-1
        return i & -i;
    }
    /**
     * 返回i的二进制从头开始有多少个0
     * @param i
     * @return int 
     */
    public static int numberOfLeadingZeros(long i) {
        //i为0,则有64个0
         if (i == 0)
            return 64;
        int n = 1;
        // 使用二分查找(也就是折半查找)思想,
        // 看右移16、24、28、30、31位的结果是否为0
        int x = (int)(i >>> 32);
        if (x == 0) { n += 32; x = (int)i; }
        if (x >>> 16 == 0) { n += 16; x <<= 16; }
        if (x >>> 24 == 0) { n +=  8; x <<=  8; }
        if (x >>> 28 == 0) { n +=  4; x <<=  4; }
        if (x >>> 30 == 0) { n +=  2; x <<=  2; }
        n -= x >>> 31;
        return n;
    }
    /**
     * 返回i的二进制从尾开始有多少个0
     * 基于二分查找
     * @param i
     * @return int 返回类型
     */
    public static int numberOfTrailingZeros(long i) {
        // HD, Figure 5-14
        int x, y;
        if (i == 0) return 64;
        int n = 63;
        y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
        y = x <<16; if (y != 0) { n = n -16; x = y; }
        y = x << 8; if (y != 0) { n = n - 8; x = y; }
        y = x << 4; if (y != 0) { n = n - 4; x = y; }
        y = x << 2; if (y != 0) { n = n - 2; x = y; }
        return n - ((x << 1) >>> 31);
    }
    /**
     * 返回指定 long 值的二进制补码表示形式中的 1 位的数量。
     * 此功能有时被称为填充计算。 
     * @param i
     * @return int 
     */
     public static int bitCount(long i) {
        // 每两位一组统计看有多少个1
        // 0x55555555也就是01010101010101010101010101010101
        i = i - ((i >>> 1) & 0x5555555555555555L);
        // 每四位一组统计看有多少个1
        // 0x33333333也就是110011001100110011001100110011
        i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
        // 每八位的1的个数
        // 0x0f0f0f0f也就是00001111000011110000111100001111
        i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
        // 每16位
        i = i + (i >>> 8);
        // 每32位
        i = i + (i >>> 16);
        // 每64位
        i = i + (i >>> 32);
        // 最终与0x7f进行与运算,得到的结果,就是1的个数
        return (int)i & 0x7f;
     }
    /**
     * 返回根据指定的位数循环左移指定的 long 值的二进制补码表示形式而得到的值。
     * (位是从左边(即高位)移出,从右边(即低位)再进入)
     * 注意,使用负距离的左循环等同于右循环:
     * rotateLeft(val, -distance) == rotateRight(val, distance)。
     * 还要注意的是,以 32 的任何倍数进行的循环都是无操作指令,
     * 因此,即使距离为负,除了最后五位外,
     * 其余所有循环距离都可以忽略:
     * rotateLeft(val, distance) == rotateLeft(val, distance & 0x1F)。 
     * @param i
     * @param distance
     * @return long 
     */
    public static long rotateLeft(long i, int distance) {
        return (i << distance) | (i >>> -distance);
    }
    /**
     * 返回根据指定的位数循环右移指定的 long 值的二进制补码表示形式而得到的值。
     * (位是从右边(即低位)移出,从左边(即高位)再进入) 
     * 注意,使用负距离的右循环等同于左循环:
     * rotateRight(val, -distance) == rotateLeft(val, distance)。
     * 还要注意的是,以 32 的任何倍数进行的循环都是无操作指令,
     * 因此,即使距离为负,除了最后五位外,
     * 其余所有循环距离都可以忽略:
     * rotateRight(val, distance) == rotateRight(val, distance & 0x1F)。 
     * @param i
     * @param distance
     * @return long 
     */
    public static long rotateRight(long i, int distance) {
        return (i >>> distance) | (i << -distance);
    }
    /**
     * 对i进行反转,反转也就是第1位和第64位对调,第2位和第63位对调等
     * @param i
     * @return int 
     */
    public static long reverse(long i) {
        // 将相邻两位进行对调
        i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
        // 将相邻四位进行对调
        i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
        // 将相邻的八位进行对调
        i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
     // 将相邻的十六位进行对调
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        // 64位中的中间32对调,最高十六位和最低十六位对调
        i = (i << 48) | ((i & 0xffff0000L) << 16) |
            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
        return i;
    }
    /**
     * 返回指定 long 值的符号函数。(如果指定值为负,则返回 -1;
     * 如果指定值为零,则返回 0;如果指定的值为正,则返回 1。) 
     * @param i
     * @return int 
     */
    public static int signum(long i) {
        // HD, Section 2-7
        return (int) ((i >> 63) | (-i >>> 63));
    }
    /**
     * 返回通过反转指定 long 值的二进制补码表示形式中字节的顺序而获得的值
     * @param i
     * @return long 
     */
    public static long reverseBytes(long i) {
        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
        return (i << 48) | ((i & 0xffff0000L) << 16) |
            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
    }
    // 序列号
    private static final long serialVersionUID = 4290774380558885855L;
}

参考:JDK 1.6 API

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件求生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值