Long源码详解

Long类将原始类型long的值包装在一个对象中。

一、继承关系图

在这里插入图片描述

二、Long类介绍

1、静态和非静态属性

@Native public static final long MIN_VALUE = 0x8000000000000000L;

@Native public static final long MAX_VALUE = 0x7fffffffffffffffL;

public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");

private final long value;

@Native public static final int SIZE = 64;

public static final int BYTES = SIZE / Byte.SIZE;

2、静态方法

public static String toString(long i, int radix) {
	// 判断进制是否出界
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        radix = 10;
    if (radix == 10)
        return toString(i);
    // 这里赋值65是因为最小long类型的整数是64位,再加上一个负号正好65位
    char[] buf = new char[65];
    int charPos = 64;
    boolean negative = (i < 0);

    if (!negative) {
        i = -i;
    }

    while (i <= -radix) {
    	// 从后往前赋值
        buf[charPos--] = Integer.digits[(int)(-(i % radix))];
        i = i / radix;
    }
    buf[charPos] = Integer.digits[(int)(-i)];

    if (negative) {
        buf[--charPos] = '-';
    }

    return new String(buf, charPos, (65 - charPos));
}

public static String toString(long i) {
    if (i == Long.MIN_VALUE)
        return "-9223372036854775808";
    // 返回数字i的位数
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    char[] buf = new char[size];
    // getChars方法和Integer中的思路一致下
    getChars(i, size, buf);
    return new String(buf, true);
}

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转成以radix进制显示的字符串形式。

public static String toUnsignedString(long i, int radix) {
	// 当i大于等于0时,无符号数就是它本身
    if (i >= 0)
        return toString(i, radix);
    // 当i小于0的时候,就等于-i + 1
    else {
        switch (radix) {
        case 2:
            return toBinaryString(i);

        case 4:
            return toUnsignedString0(i, 2);

        case 8:
            return toOctalString(i);

        case 10:
            /*
             * We can get the effect of an unsigned division by 10
             * on a long value by first shifting right, yielding a
             * positive value, and then dividing by 5.  This
             * allows the last digit and preceding digits to be
             * isolated more quickly than by an initial conversion
             * to BigInteger.
             */
            // 先逻辑右移一位,再除以五
            // 在Integer中是通过先转换为Long再计算的
            // Long也可以先转换为BigInteger来计算
            // 但是这样算效率更高
            long quot = (i >>> 1) / 5;
            long rem = i - quot * 10;
            return toString(quot) + rem;

        case 16:
            return toHexString(i);

        case 32:
            return toUnsignedString0(i, 5);

        default:
        	// BigInteger类型的toString方法就不介绍了,有机会讲解BigInteger类型源码
            return toUnsignedBigInteger(i).toString(radix);
        }
    }
}

public static String toBinaryString(long i) {
    return toUnsignedString0(i, 1);
}

public static String toOctalString(long i) {
    return toUnsignedString0(i, 3);
}

public static String toHexString(long i) {
    return toUnsignedString0(i, 4);
}

static String toUnsignedString0(long val, int shift) {
    // assert shift > 0 && shift <=5 : "Illegal shift value";
    // 算出一共有多少位bit
    int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
    int chars = Math.max(((mag + (shift - 1)) / shift), 1);
    char[] buf = new char[chars];

    formatUnsignedLong(val, shift, buf, 0, chars);
    return new String(buf, true);
}

// 将val整数以radix进制从offset + len开始倒序存储在buf数组中
static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
    int charPos = len;
    int radix = 1 << shift;
    int mask = radix - 1;
    do {
        buf[offset + --charPos] = Integer.digits[((int) val) & mask];
        val >>>= shift;
    } while (val != 0 && charPos > 0);

    return charPos;
}

// 返回BigInteger类型
private static BigInteger toUnsignedBigInteger(long i) {
    if (i >= 0L)
        return BigInteger.valueOf(i);
    else {
        int upper = (int) (i >>> 32);
        int lower = (int) i;

        // return (upper << 32) + lower
        // 将高位左移32位与低位合并
        return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
            add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
    }
}

返回radix进制的无符号整数。

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') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Long.MIN_VALUE;
            } else if (firstChar != '+')
                throw NumberFormatException.forInputString(s);

            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++;
        }
        multmin = limit / radix;
        while (i < len) {
            // 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);
    }
    return negative ? result : -result;
}

public static long parseLong(String s) throws NumberFormatException {
    return parseLong(s, 10);
}

将radix进制的String类型转换为long类型,和Integer一样。

public static long parseUnsignedLong(String s, int radix)
            throws NumberFormatException {
    if (s == null)  {
        throw new NumberFormatException("null");
    }

    int len = s.length();
    if (len > 0) {
        char firstChar = s.charAt(0);
        if (firstChar == '-') {
            throw new
                NumberFormatException(String.format("Illegal leading minus sign " +
                                                   "on unsigned string %s.", s));
        } else {
            if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
                (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
                return parseLong(s, radix);
            }

            // No need for range checks on len due to testing above.
            long first = parseLong(s.substring(0, len - 1), radix);
            int second = Character.digit(s.charAt(len - 1), radix);
            if (second < 0) {
                throw new NumberFormatException("Bad digit at end of " + s);
            }
            long result = first * radix + second;
            if (compareUnsigned(result, first) < 0) {
                /*
                 * The maximum unsigned value, (2^64)-1, takes at
                 * most one more digit to represent than the
                 * maximum signed value, (2^63)-1.  Therefore,
                 * parsing (len - 1) digits will be appropriately
                 * in-range of the signed parsing.  In other
                 * words, if parsing (len -1) digits overflows
                 * signed parsing, parsing len digits will
                 * certainly overflow unsigned parsing.
                 *
                 * The compareUnsigned check above catches
                 * situations where an unsigned overflow occurs
                 * incorporating the contribution of the final
                 * digit.
                 */
                throw new NumberFormatException(String.format("String value %s exceeds " +
                                                              "range of unsigned long.", s));
            }
            return result;
        }
    } else {
        throw NumberFormatException.forInputString(s);
    }
}

public static long parseUnsignedLong(String s) throws NumberFormatException {
    return parseUnsignedLong(s, 10);
}

将无符号的radix进制的字符串转换为long类型。

public static Long valueOf(String s, int radix) throws NumberFormatException {
    return Long.valueOf(parseLong(s, radix));
}

// 有缓存就从缓存中拿
public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

将radix进制字符串转换为Long类型。

public static Long decode(String nm) throws NumberFormatException {
    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);
    // 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 = Long.valueOf(nm.substring(index), radix);
        result = negative ? Long.valueOf(-result.longValue()) : result;
    } catch (NumberFormatException e) {
        // If number is Long.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 = Long.valueOf(constant, radix);
    }
    return result;
}

将带有进制表示的字符串转换为Long类型。

public static Long getLong(String nm) {
    return getLong(nm, null);
}

public static Long getLong(String nm, Long val) {
    String v = null;
    try {
        v = System.getProperty(nm);
    } catch (IllegalArgumentException | NullPointerException e) {
    }
    if (v != null) {
        try {
            return Long.decode(v);
        } catch (NumberFormatException e) {
        }
    }
    return val;
}

从系统属性中获取一个名为nm的Long类型的值。

public static long divideUnsigned(long dividend, long divisor) {
    if (divisor < 0L) { // signed comparison
        // Answer must be 0 or 1 depending on relative magnitude
        // of dividend and divisor.
        return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;
    }

    if (dividend > 0) //  Both inputs non-negative
        return dividend/divisor;
    else {
        /*
         * For simple code, leveraging BigInteger.  Longer and faster
         * code written directly in terms of operations on longs is
         * possible; see "Hacker's Delight" for divide and remainder
         * algorithms.
         */
        return toUnsignedBigInteger(dividend).
            divide(toUnsignedBigInteger(divisor)).longValue();
    }
}

public static long remainderUnsigned(long dividend, long divisor) {
    if (dividend > 0 && divisor > 0) { // signed comparisons
        return dividend % divisor;
    } else {
        if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor
            return dividend;
        else
            return toUnsignedBigInteger(dividend).
                remainder(toUnsignedBigInteger(divisor)).longValue();
    }
}

// 返回最高位
public static long highestOneBit(long i) {
    // HD, Figure 3-1
    i |= (i >>  1);
    i |= (i >>  2);
    i |= (i >>  4);
    i |= (i >>  8);
    i |= (i >> 16);
    i |= (i >> 32);
    return i - (i >>> 1);
}

// 返回最低位
public static long lowestOneBit(long i) {
    // HD, Section 2-1
    return i & -i;
}

// 最低位连续为0的个数
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);
}

public static int bitCount(long i) {
    // HD, Figure 5-14
    i = i - ((i >>> 1) & 0x5555555555555555L);
    i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
    i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    i = i + (i >>> 32);
    return (int)i & 0x7f;
 }

public static long rotateLeft(long i, int distance) {
    return (i << distance) | (i >>> -distance);
}

public static long rotateRight(long i, int distance) {
    return (i >>> distance) | (i << -distance);
}

public static long reverse(long i) {
    // HD, Figure 7-1
    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;
    i = (i << 48) | ((i & 0xffff0000L) << 16) |
        ((i >>> 16) & 0xffff0000L) | (i >>> 48);
    return i;
}

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

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

缓存 -128-127的数。

3、方法介绍

public Long(long value) {
    this.value = value;
}

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

构造方法。

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

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

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

public long longValue() {
    return value;
}

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

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

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

实现Number接口的方法。

public int hashCode() {
    return Long.hashCode(value);
}

public static int hashCode(long value) {
    return (int)(value ^ (value >>> 32));
}

这里hashCode要返回一个int类型,但是long的hashCode不能与高位无关,所以这里它低位与高位做或非运算。

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}
public int compareTo(Long anotherLong) {
    return compare(this.value, anotherLong.value);
}

public static int compare(long x, long y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

public static int compareUnsigned(long x, long y) {
    return compare(x + MIN_VALUE, y + MIN_VALUE);
}

Long中的许多静态方法和Integer类一致。
完结撒花★,°:.☆( ̄▽ ̄)/$:.°★

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值